home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / prog / cport2.zip / CPORT.DOC < prev    next >
Text File  |  1993-04-09  |  191KB  |  5,568 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.             Cport
  8.  
  9.             Serial Communications Library for C/C++
  10.             Version 2.0
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.    Copyright (c) 1993  Bri Productions - all rights reserved
  19.  
  20.    Cport is a registered trademark of Bri Productions. All other product and
  21.    brand names are trademarks or registered trademarks of their respective
  22.    holders.
  23.  
  24.                                  i
  25.  
  26.  
  27. Contents
  28. ========
  29.  
  30.    Introduction
  31.    ------------
  32.       General Description ............................. 1-1
  33.       Disclaimer ...................................... 1-2
  34.       Evaluation Copy ................................. 1-2
  35.       Purchase Version ................................ 1-2
  36.       Contacting  Bri Productions ..................... 1-2
  37.       Terminology ..................................... 1-3
  38.  
  39.    Using Cport
  40.    -----------
  41.       Basics .......................................... 2-1
  42.       Buffered Input .................................. 2-3
  43.       Buffered Output ................................. 2-5
  44.       Handshaking ..................................... 2-7
  45.       Direct Transmit Mode ............................ 2-10
  46.  
  47.    Theory of Operation
  48.    -------------------
  49.       The UART ........................................ 3-1
  50.       The Transmitter and Receiver .................... 3-1
  51.       The Transmit and Receive Queues ................. 3-2
  52.       Input and Output Functions ...................... 3-2
  53.       Control and Status Functions .................... 3-2
  54.       Direct Transmit mode ............................ 3-2
  55.  
  56.    C Reference
  57.    -----------
  58.       Typedefs and Structures ......................... 4-1
  59.          COM .......................................... 4-2
  60.          CPARAM ....................................... 4-2
  61.          byte ......................................... 4-3
  62.  
  63.       Global Variables ................................ 4-4
  64.          comopen_errno ................................ 4-4
  65.  
  66.       Control Functions ............................... 4-5
  67.          ComOpen ...................................... 4-6
  68.          ComOpenS ..................................... 4-8
  69.          ComClose ..................................... 4-8
  70.          ComCloseAll .................................. 4-9
  71.          ComHandshake ................................. 4-9
  72.          ComParam ..................................... 4-10
  73.          ComBaud ...................................... 4-11
  74.          ComMode ...................................... 4-12
  75.          ComRxQ ....................................... 4-13
  76.          ComTxQ ....................................... 4-14
  77.          ComTx ........................................ 4-15
  78.          ComNS550 ..................................... 4-15
  79.          ComTurbo ..................................... 4-16
  80.  
  81.                                  ii
  82.  
  83.  
  84.       Input Functions ................................. 4-18
  85.          ComGetc ...................................... 4-19
  86.          ComGets ...................................... 4-19
  87.          ComIn ........................................ 4-20
  88.          ComFlushRx ................................... 4-21
  89.          ComLenRx ..................................... 4-22
  90.          ComPeek ...................................... 4-22
  91.          ComRxScan .................................... 4-23
  92.  
  93.       Output Functions ................................ 4-25
  94.          ComPutc ...................................... 4-26
  95.          ComPuts ...................................... 4-26
  96.          ComOut ....................................... 4-27
  97.          ComFlushTx ................................... 4-28
  98.          ComLenTx ..................................... 4-29
  99.          ComTxWait .................................... 4-29
  100.  
  101.       Status Functions ................................ 4-31
  102.          ComError ..................................... 4-32
  103.          ComStatus .................................... 4-33
  104.          ComRts ....................................... 4-33
  105.          ComDtr ....................................... 4-34
  106.          ComOut1 ...................................... 4-35
  107.          ComUart ...................................... 4-35
  108.  
  109.       Data Integrity .................................. 4-37
  110.          ComChecksum .................................. 4-38
  111.          ComCrc16 ..................................... 4-38
  112.          ComCrc32 ..................................... 4-39
  113.  
  114.       Misc Functions .................................. 4-41
  115.          ComSetBreak .................................. 4-42
  116.          ComClrBreak .................................. 4-42
  117.          ComPutScrtch ................................. 4-43
  118.          ComGetScrtch ................................. 4-43
  119.  
  120.    C++ Reference
  121.    -------------
  122.       Control Functions ............................... 5-1
  123.          Cport::Cport ................................. 5-2
  124.          Cport::operator int .......................... 5-4
  125.          Cport::Handshake ............................. 5-5
  126.          Cport::Param ................................. 5-6
  127.          Cport::Baud .................................. 5-6
  128.          Cport::Mode .................................. 5-7
  129.          Cport::RxQ ................................... 5-8
  130.          Cport::TxQ ................................... 5-9
  131.          Cport::Tx .................................... 5-10
  132.          Cport::NS550 ................................. 5-10
  133.          Cport::Turbo ................................. 5-11
  134.  
  135.                                  iii
  136.  
  137.  
  138.       Input Functions ................................. 5-13
  139.          Cport::Get ................................... 5-14
  140.          Cport::In .................................... 5-15
  141.          Cport::FlushRx ............................... 5-16
  142.          Cport::LenRx ................................. 5-17
  143.          Cport::Peek .................................. 5-17
  144.          Cport::RxScan ................................ 5-18
  145.  
  146.       Output Functions ................................ 5-19
  147.          Cport::Put ................................... 5-20
  148.          Cport::Out ................................... 5-21
  149.          Cport::FlushTx ............................... 5-22
  150.          Cport::LenTx ................................. 5-22
  151.          Cport::TxWait ................................ 5-23
  152.  
  153.       Status Functions ................................ 5-24
  154.          Cport::Error ................................. 5-25
  155.          Cport::Status ................................ 5-25
  156.          Cport::Rts ................................... 5-26
  157.          Cport::Dtr ................................... 5-27
  158.          Cport::Out1 .................................. 5-28
  159.          Cport::Uart .................................. 5-28
  160.  
  161.       Data Integrity .................................. 5-29
  162.          Cport::Checksum .............................. 5-30
  163.          Cport::Crc16 ................................. 5-30
  164.          Cport::Crc32 ................................. 5-31
  165.  
  166.       Misc Functions .................................. 5-33
  167.          Cport::SetBreak .............................. 5-34
  168.          Cport::ClrBreak .............................. 5-34
  169.          Cport::Scratch ............................... 5-35
  170.  
  171.    File Transfer
  172.    -------------
  173.       Xmodem .......................................... 6-1
  174.       XmodemTx ........................................ 6-2
  175.       XmodemRx ........................................ 6-3
  176.       Xcallback ....................................... 6-4
  177.       Callback Function ............................... 6-5
  178.       Xmodem Tables of Values ......................... 6-7
  179.  
  180.    Appendix
  181.    --------
  182.       Appendix A - Tables of Values ................... A-1
  183.       Appendix B - Compiling and Linking .............. B-1
  184.       Appendix C - Order form ......................... C-1
  185.  
  186.                                  1-1
  187.  
  188.  
  189. Introduction
  190. ============
  191.  
  192.    General Description
  193.    -------------------
  194.       Cport is a general purpose C/C++ serial communications library for
  195.       80x86 Intel processor-based systems and the National Semiconductor
  196.       family of UARTs. This includes IBM and compatible computers and
  197.       potentially 80x86 processor-based embedded applications. The latter
  198.       is usually possible with few no modifications.
  199.  
  200.       Cport features:
  201.          ■ Support for COM 1 to COM 4 and custom configurations
  202.          ■ Simultaneous serial communications.
  203.          ■ Baud rates from 50 to 115200 baud.
  204.          ■ Built-in hardware and software handshaking.
  205.          ■ Both transmitter and receiver are interrupt-driven.
  206.          ■ Adjustable transmit and receive queues.
  207.          ■ Queues as large as 65534 bytes each.
  208.          ■ Transmit and receive queues are handled internally.
  209.          ■ Supports the NS16550 UART automatically.
  210.          ■ Developed in assembly language for optimum speed and efficiency.
  211.  
  212.       Cport provides a middle level C/C++ interface for general purpose
  213.       serial communications. The library is lean and fast, so as to
  214.       provide programs with high performance serial communications without
  215.       significantly increasing its size. Cport can be used to develop
  216.       higher level interfaces for specific types of serial devices or as
  217.       is for more generic types of serial communications applications. An
  218.       example of a higher level interface might be a set of functions
  219.       that communicate with a serial printer. This interface would have
  220.       more knowledge of the type of data, controls codes, protocol, etc.
  221.       that relate to a serial printer. An example of a more generic
  222.       application would be a terminal program since, like Cport, a
  223.       terminal program is indifferent to the actual significance of the
  224.       data. 
  225.       
  226.       The design philosophy of Cport is to provide as many features
  227.       as possible without hindering its most important attributes: speed
  228.       and size. Many of the details, in addition to the actual hardware
  229.       interface itself, are provided in order to facilitate serial
  230.       communications software development. This includes the internal
  231.       buffering (queues), hardware and software handshaking and different
  232.       flavors of input/output functions. These features would either need
  233.       to be implemented externally anyway, or do not add overhead unless used. 
  234.       
  235.       Many features, such as timeouts, can additionally be easily implemented 
  236.       as needed at the middle, C/C++ level. Many techniques and features are 
  237.       demonstrated in the next section (Using Cport) and in examples 
  238.       throughout this document. Examples and techniques will continue 
  239.       to be compiled and made available in the future.
  240.  
  241.                                  1-2
  242.  
  243.  
  244.  
  245.    DISCLAIMER
  246.    ----------
  247.       Cport is provided AS IS. Bri Productions specifically disclaims any
  248.       and all warranties, expressed or implied, including but not limited
  249.       to any implied warranties including fitness for a particular purpose.
  250.       Use this product at your own risk.
  251.  
  252.  
  253.    Evaluation Copy
  254.    ---------------
  255.       This is an evaluation copy of Cport. This evaluation copy is
  256.       provided to you at no charge* so that you may properly evaluate Cport
  257.       prior to purchasing it. This evaluation copy has a fully functional
  258.       small model library and contains no cripples. Redistribution of this
  259.       evaluation copy, unaltered and without charge, is encouraged.
  260.  
  261.       We feel it is important that you be able to try a product prior
  262.       to paying for it. This ensures that you will be able to determine
  263.       the quality of a product and if it fits your needs. It avoids
  264.       the hassle of money back guarantees which would otherwise waste
  265.       your time and ours.
  266.  
  267.       We also feel that the producers of a product are entitled to be
  268.       compensated for their hard work. This enables them to continue to
  269.       provide a high quality product. If you intend to use Cport beyond
  270.       the purpose evaluation, you are obligated to purchase a license.
  271.  
  272.       * Disk distributors may charge a minimum (reasonable) fee for
  273.       distribution of this evaluation copy.
  274.  
  275.  
  276.    Licensing
  277.    ---------
  278.       When you purchase a license for Cport, you will receive the small,
  279.       medium, compact, large and huge model libraries; Library source code;
  280.       Printed manual; and examples. You will also be entitled to
  281.       technical support and low cost upgrades. When you license Cport you
  282.       may incorporate any part of it into your own executable programs
  283.       without additional royalties as long as they bear your own valid
  284.       Copyright notice. Each lisense covers usage by a single person at a
  285.       time. An order form is provided in Appendix C.
  286.  
  287.  
  288.    Contacting  Bri Productions
  289.    ---------------------------
  290.       Bri Productions may be contacted by any of the following means:
  291.  
  292.               Telephone: (510) 794-0616
  293.  
  294.              CompuServe: 76635,2246
  295.  
  296.               U.S. mail: Bri Productions
  297.                          P.O.Box 7121
  298.                          Fremont, CA 94537-7121
  299.  
  300.                                  1-3
  301.  
  302.  
  303.    Terminology
  304.    -----------
  305.       This section defines some of the terminology used in this and other
  306.       Cport documentation. 
  307.       
  308.       The 'computer' refers to the machine on which Cport is running. 
  309.       'Remote device' refers to the device the computer is communicating 
  310.       with. The actual device may be a modem, serial printer or other 
  311.       communications device. 
  312.       
  313.       If a serial port is, 'open' it is currently performing or ready to 
  314.       perform serial communications. All 'open' serial ports have a 'handle' 
  315.       which is assigned when it is 'opened'. This 'handle' is passed to Cport 
  316.       functions in order to identify the 'open' serial port the function is to 
  317.       act upon. (In C++, instances of the Cport class are used instead of 
  318.       handles). 
  319.       
  320.       Individual units of 'data' that are transmitted and received may be 
  321.       referred to as 'characters' or 'bytes'. Technically, there is no 
  322.       difference between 'characters' and bytes, however; 'characters' 
  323.       usually refer to 7 or 8 bit ASCII values and 'bytes' typically refer to 
  324.       8 bit binary data. 'Data' refers to 'characters'/'bytes' in general.
  325.  
  326.       A 'signal' may refer to software (i.e. control characters) as well
  327.       as actual hardware lines. This mainly refers to XON (ctrl-Q) and
  328.       XOFF (ctrl-S), which are used in software handshaking. 'Signals' may
  329.       be either inputs or outputs. A 'signal' is said to be 'asserted' if
  330.       it is in a true/on state and 'inhibited' if it is in a false/off
  331.       state. This stems from the idea that a 'signal' can be used to allow
  332.        (assert) or preclude (inhibit) something such as the transmission of
  333.       'data'.
  334.  
  335.                                  2-1
  336.  
  337.  
  338. Using Cport
  339. ===========
  340.  
  341.    Basics
  342.    ------
  343.       Before a serial port can be accessed, it must be opened. The open
  344.       functions identify the serial port by it's port address and
  345.       interrupt request line. The parameter id contains the port base
  346.       address in the lower 12 bits and the irq number in the upper 4 bits
  347.       of id. The open functions also take parameters that describe the
  348.       baud rate, word length, number of stop bits, parity check, and
  349.       transmit and receive queue sizes. If a serial port is successfully
  350.       opened, a handle to the newly opened serial port is returned to the
  351.       caller. This handle is used to reference the serial port in
  352.       subsequent calls to Cport functions. (C++ uses instances of the
  353.       Cport class instead of handles). If the serial port cannot be
  354.       opened, the open function returns NULL and sets the global variable
  355.       'comopen_errno' to an error code. (C++ uses an int typecast instead
  356.       of the global variable to hold the error code).
  357.  
  358.       Before a program terminates, the serial port must be closed to make
  359.       certain restorations. Failing to close a serial port will leave
  360.       these restorations undone and almost certainly cause the system to
  361.       lock up. In C++, the serial port is closed automatically when it goes
  362.       out of scope (destructor).
  363.  
  364.  
  365.                                  2-2
  366.  
  367.  
  368.       C Example:
  369.  
  370.             #include <stdio.h>
  371.             #include "cport.h"
  372.  
  373.             int main(void)
  374.             {
  375.             COM com;      /* declare a serial port handle */
  376.  
  377.                   /* Open the serial port and get/store the serial port handle
  378.                   */
  379.                com = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
  380.  
  381.  
  382.                   /* Check for a NULL handle. If the handle is NULL check
  383.                   // comopen_errno for the cause
  384.                   */
  385.                if(com == NULL)
  386.                {
  387.                   puts("ERROR: unable to open serial port");
  388.                   return(comopen_errno);
  389.                }
  390.  
  391.                   /* Put a string to the newly opened serial port
  392.                   */
  393.                ComPuts(com, "Hello Cport");
  394.  
  395.                   ... The rest of the program here
  396.  
  397.                   /* Close the serial port before exiting
  398.                   */
  399.                ComClose(com);
  400.                return(0);
  401.             }
  402.  
  403.       C++ Example:
  404.  
  405.             #include <iostream.h>
  406.             #include "cport.h"
  407.  
  408.             int main(void)
  409.             {
  410.                Cport com(COM1, B9600, W8|S1|NONE, 1024, 512);
  411.                if((int)com != NO_ERR)   // uses int typecast
  412.                {
  413.                   cout << "ERROR: unable to open serial port" << endl;
  414.                   return(com);
  415.                }
  416.                com.Put("Hello Cport");
  417.  
  418.                   ... The rest of the program here
  419.  
  420.                // The serial port is closed automatically by
  421.                // the destructor.
  422.  
  423.                return(0);
  424.             }
  425.  
  426.                                  2-3
  427.  
  428.  
  429.    Buffered Input
  430.    --------------
  431.       When data is received, it is placed into the receive queue and stays
  432.       there until an input function retrieves it. Input functions will
  433.       only fetch whatever data is existing in the receive queue at
  434.       the time the input function is called. If a specified length of data
  435.       is expected, the receive queue can be queried to determine if enough
  436.       data is available to call an input function. This is a common case
  437.       with serial devices that send specific length messages terminated
  438.       by a specific character (often '\n' or '\r'). In the examples, the
  439.       function fetches a message only if one is available. If the message
  440.       is not available, it returns a zero, If a message is available, the
  441.       measurement is copied to the caller's buffer and a 1 is returned.
  442.  
  443.       C Example:
  444.  
  445.             #define   MSG_LEN      24
  446.             #define   TERM_C      '\n'
  447.  
  448.             int GetMessage(COM com, char *buf)
  449.             {
  450.                if(ComLenRx(com) > MSG_LEN)
  451.                {
  452.                   ComGets(com, buf, MSG_LEN, TERM_C);
  453.                   return(1);
  454.                }
  455.                return(0);
  456.             }
  457.  
  458.       C++ Example:
  459.  
  460.             #define   MSG_LEN   24
  461.             #define   TERM_C   '\n'
  462.  
  463.             int GetMessage(Cport& com, char *buf)
  464.             {
  465.                if(com.LenRx() > MSG_LEN)
  466.                {
  467.                   com.Get(buf, MSG_LEN, TERM_C);
  468.                   return(1);
  469.                }
  470.                return(0);
  471.             }
  472.  
  473.       If the messages are not of a specific length, the receive queue can
  474.       be scanned for a particular character, namely the termination
  475.       character. Scanning for a character is also possible with specific
  476.       length messages but is slower than checking the length of the
  477.       receive queue. In the following examples, the function fetches a
  478.       message only if one is available. If the message is not available it
  479.       returns a zero, If a message is available, the measurement is
  480.       copied to the caller's buffer and a 1 is returned. If the message
  481.       is longer that the specified maximum message length, a -1 is
  482.       returned.
  483.  
  484.                                  2-4
  485.  
  486.  
  487.       C Example:
  488.  
  489.             #define   MAX_MSG_LEN      80
  490.             #define   TERM_C            '\n'
  491.  
  492.             int GetMessage(COM com, char *buf)
  493.             {
  494.             int len;
  495.  
  496.                len = ComRxScan(com, TERM_C);
  497.                if(len > MAX_MSG_LEN)
  498.                   return(-1);
  499.  
  500.                else if(len > 0)
  501.                   ComGets(com, buf, MAX_MSG_LEN, TERM_C);
  502.  
  503.                return(len != 0);
  504.             }
  505.  
  506.       C++ Example:
  507.  
  508.             #define   MAX_MSG_LEN      80
  509.             #define   TERM_C            '\n'
  510.  
  511.             int GetMessage(Cport& com, char *buf)
  512.             {
  513.             int len;
  514.  
  515.                len = com.RxScan(TERM_C);
  516.                if(len > MAX_MSG_LEN)
  517.                   return(-1);
  518.  
  519.                else if(len > 0)
  520.                   com.Get(buf, MAX_MSG_LEN, TERM_C);
  521.  
  522.                return(len != 0);
  523.             }
  524.  
  525.       The previous examples are ideal for event driven routines. They do
  526.       not wait for a message to be received if one is not ready.
  527.       This allows a program to process other tasks instead of holding up
  528.       program execution while waiting for a message. On the contrary, one
  529.       may want to wait for a message, perhaps within a certain time frame. 
  530.       Revisiting the first example, we can add a timeout using the ANSI C 
  531.       compatible function, clock.
  532.  
  533.                                  2-5
  534.  
  535.  
  536.       C Example:
  537.  
  538.             #include <time.h>
  539.             #define   MSG_LEN      24
  540.             #define   TERM_C      '\n'
  541.  
  542.             int GetMessage(COM com, char *buf, clock_t timeout)
  543.             {
  544.                timeout += clock();
  545.                while(ComLenRx(com) <= MSG_LEN)
  546.                {
  547.                   if(clock() > timeout)
  548.                      return(0);
  549.                }
  550.                ComGets(com, buf, MSG_LEN, TERM_C);
  551.                return(1);
  552.             }
  553.  
  554.       C++ Example:
  555.  
  556.             #include <time.h>
  557.             #define   MSG_LEN   24
  558.             #define   TERM_C   '\n'
  559.  
  560.             int GetMessage(Cport& com, char *buf, clock_t timeout)
  561.             {
  562.                timeout += clock();
  563.                while(com.LenRx() <= MSG_LEN)
  564.                {
  565.                   if(clock() > timeout)
  566.                      return(0);
  567.                }
  568.                com.Get(buf, MSG_LEN, TERM_C);
  569.                return(1);
  570.             }
  571.  
  572.    Buffered Output
  573.    ---------------
  574.       When an output function inserts data into the transmit queue, it
  575.       does not wait for the data to be transmitted before the function
  576.       returns. Instead the transmitter will subsequently remove the data,
  577.       one byte/character at a time, in the order in which it was inserted and
  578.       transmit them in the background. This allows the program to continue
  579.       with more important tasks instead of waiting for the data to
  580.       transmit at a relatively slow rate (compared to the processor).
  581.  
  582.       At certain points in a program, one may want to ensure that all the
  583.       data thus far has been transmitted. To do this the transmit queue
  584.       can be queried to determine how many bytes/characters still reside
  585.       there. The following examples make sure all data finishes
  586.       transmitting before the program is terminated.
  587.  
  588.                                  2-6
  589.  
  590.  
  591.       C Example:
  592.  
  593.             int main(void)
  594.             {
  595.             COM com;
  596.  
  597.                com = ComOpen(COM2,B9600,W8|S1|NONE,512,2048);
  598.                if(com == NULL)
  599.                   return(comopen_errno);
  600.  
  601.                ComPuts(com, "Welcome to Bri Productions");
  602.                while(ComLenTx(com) != 0);
  603.                ComClose(com);
  604.                return(0);
  605.             }
  606.  
  607.       C++ Example:
  608.  
  609.             int main(void)
  610.             {
  611.                Cport com(COM2, B9600, W8|S1|NONE, 512, 2048);
  612.                if((int)com != NO_ERR)
  613.                   return(com);
  614.  
  615.                com.Put("Welcome to Bri Productions");
  616.                while(com.LenTx() != 0);
  617.  
  618.                // The serial port is closed automatically by
  619.                // the destructor.
  620.                return(0);
  621.             }
  622.  
  623.       Querying the transmit queue can also be useful in determining if
  624.       there is enough room for new data. In the following, example a
  625.       message is sent only if there is enough room for the whole message.
  626.       The value returned should always be 0 (if not enough room) or the
  627.       length of the message (number of characters put by ComPuts).
  628.  
  629.       C Example:
  630.  
  631.             #include <string.h>
  632.             #define   TXSIZE   1024
  633.  
  634.             int PutMessage(COM com, const char *buffer)
  635.             {
  636.                if(TXSIZE - ComLenTx(com) < strlen(buffer))
  637.                   return(0);
  638.  
  639.                return(ComPuts(com, buffer));
  640.             }
  641.  
  642.                                  2-7
  643.  
  644.  
  645.        C++ Example:
  646.  
  647.             #include <string.h>
  648.             #define   TXSIZE   1024
  649.  
  650.             int PutMessage(Cport& com, const char *buffer)
  651.             {
  652.                if(TXSIZE - com.LenTx() < strlen(buffer))
  653.                   return(0);
  654.  
  655.                return(com.Put(buffer));
  656.             }
  657.  
  658.       If the transmit queue length is not checked and an output function
  659.       is called without enough room for all the data, the number of
  660.       byte/characters that did fit is returned. This value can be used
  661.       as an offset into the data to determine the first byte/character
  662.       that there was no room for. The following examples will not return
  663.       until all the characters in the message are put to the queue.
  664.  
  665.       C Example:
  666.  
  667.             void PutMessage(COM com, const char *buffer)
  668.             {
  669.             const char *_buffer = buffer;
  670.  
  671.                while(*_buffer != '\0')
  672.                   _buffer += ComPuts(com, _buffer);
  673.             }
  674.  
  675.       C++ Example:
  676.  
  677.             void PutMessage(Cport& com, const char *buffer)
  678.             {
  679.             const char *_buffer = buffer;
  680.  
  681.                while(*_buffer != '\0')
  682.                   _buffer += com.Put(_buffer);
  683.             }
  684.  
  685.  
  686.    Handshaking
  687.    -----------
  688.       There are number of built-in options available for implementing
  689.       handshaking. The options can be divided into two categories. One is
  690.       hardware handshaking and the other is software handshaking. In
  691.       hardware handshaking, one or more of the hardware lines is used.
  692.       In software handshaking, XON and XOFF characters are used.
  693.  
  694.                                  2-8
  695.  
  696.  
  697.    Hardware Handshaking
  698.    --------------------
  699.       In hardware handshaking, any combination of the hardware signals
  700.       RTS, DTR, DSR, CTS, and DCD can be used to achieve handshaking. RTS
  701.       and/or DTR are used by the receiver to signal the remote device to
  702.       suspend or resume transmitting. Similarly, DSR, CTS, and/or DCD can
  703.       be used by the remote device's receiver to signal the transmitter to
  704.       suspend or resume transmitting.
  705.  
  706.    Software Handshaking
  707.    --------------------
  708.       In software handshaking, the control characters XON (ctrl-Q) and
  709.       XOFF (ctrl-S) are used to achieve handshaking. When receiver
  710.       software handshaking (S_RX) is enabled, XON and XOFF characters are
  711.       transmitted to signal the remote device to suspend or resume it's
  712.       transmission. Notice that even though the XON and XOFF characters
  713.       are sent by the transmitter, it is the receiver that exercises the
  714.       handshaking in order to preclude a receive queue overflow. In
  715.       transmit software handshaking (S_TX), the remote device sends XON
  716.       and XOFF characters to suspend and resume the computer's
  717.       transmission. Notice that even though the XON and XOFF characters
  718.       are received, it is the transmitter that is affected. Both receive
  719.       and transmit handshaking can be enabled simultaneously.
  720.  
  721.    The Receiver
  722.    ------------
  723.       When receive software (S_RX) and/or hardware handshaking (DTR and/or
  724.       RTS) are enabled, the receiver monitors the length of the receive
  725.       queue. If the length exceeds the specified threshold, the receiver
  726.       will take the appropriate action to signal the remote device to
  727.       suspend transmitting. When the length of the receive queue
  728.       subsequently falls below half of the set threshold, the appropriate
  729.       action is taken to signal the remote device to resume transmitting.
  730.  
  731.    The Transmitter
  732.    ---------------
  733.       When transmit software (S_TX) and/or hardware handshaking (DSR, CTS,
  734.       and/or DCD) are enabled and the computer is signaled to suspend
  735.       transmitting with the corresponding handshaking enabled, the
  736.       transmitter will stop transmitting. Subsequently, when the computer
  737.       is signaled to resume transmitting, the transmitter will pick up
  738.       where it left off.
  739.  
  740.    User Handshaking
  741.    ----------------
  742.       Another option for implementing handshaking is for the programmer to
  743.       implement their own handshaking scheme. To accomplish this, Cport
  744.       provides the function ComTx. ComTx allows the programmer to turn the
  745.       transmitter on and off. When the transmitter is turned off,
  746.       transmitting halts immediately. If any characters still reside in
  747.       the transmit queue, they will remain there until the transmitter is
  748.       turned back on or the transmit queue is flushed. More characters may
  749.       be put into the transmit queue while the transmitter is turned off.
  750.  
  751.                                  2-9
  752.  
  753.  
  754.    Cooperation
  755.    -----------
  756.       In any handshaking scheme, it is imperative that the computer and
  757.       the remote device recognize the same handshaking scheme. For
  758.       instance, if the remote device recognizes hardware handshaking and
  759.       the computer does not, the computer will ignore any requests by the
  760.       remote device to suspend transmitting. If the remote device
  761.       recognized software handshaking and the computer did not, bogus XON
  762.       and XOFF characters might corrupt the received data.
  763.  
  764.       In the first example, the transmitter will not transmit unless CTS
  765.       and DSR are asserted. The receiver will inhibit RTS if the receive
  766.       queue exceeds 768 bytes/characters and assert it when it
  767.       subsequently falls below 768 / 2. In the second example, the
  768.       transmitter will stop if an XOFF character is received and restart
  769.       when an XON character is received. If the receive queue length
  770.       exceeds 768 bytes/characters, an XOFF character will be transmitted
  771.       and when the length subsequently falls below 768 / 2, an XON
  772.       character is transmitted.
  773.  
  774.       C Example 1
  775.  
  776.             int main(void)
  777.             {
  778.             COM com;
  779.  
  780.                com = ComOpen(COM1, B9600, W7|S1|EVEN, 1024,256);
  781.                if(com == NULL)
  782.                   return(comopen_errno);
  783.  
  784.                ComHandshake(com, CTS | DSR | RTS, 768);
  785.  
  786.                /* rest of the program */
  787.  
  788.                ComClose(com);
  789.                return(0);
  790.             }
  791.  
  792.  
  793.       C++ Example 1
  794.  
  795.             int main(void)
  796.             {
  797.                Cport com(COM1, B9600, W7|S1|EVEN, 1024, 256, CTS|DSR|RTS, 768);
  798.                if((int)com)
  799.                   return(com);
  800.  
  801.                // rest of the program
  802.                return(0);
  803.             }
  804.  
  805.                                    2-10
  806.  
  807.  
  808.       C Example 2
  809.  
  810.             int main(void)
  811.             {
  812.             COM com;
  813.  
  814.                com = ComOpen(COM1, B9600, W7|S1|EVEN, 1024, 256);
  815.                if(com == NULL)
  816.                   return(comopen_errno);
  817.  
  818.                ComHandshake(com, SOFT, 768); /* SOFT == S_RX | S_TX */
  819.  
  820.                /* rest of the program */
  821.  
  822.                ComClose(com);
  823.                return(0);
  824.             }
  825.  
  826.       C++ Example 2
  827.  
  828.             int main(void)
  829.             {
  830.                                                       // SOFT == S_RX | S_TX
  831.                Cport com(COM1, B9600, W7|S1|EVEN, 1024, 256, SOFT, 768);
  832.                if((int)com)
  833.                   return(com);
  834.  
  835.                // rest of the program
  836.  
  837.                return(0);
  838.             }
  839.  
  840.    Direct Transmit Mode
  841.    --------------------
  842.       In direct transmit mode, data is sent directly to the serial port.
  843.       The output functions will only return after all the data has been
  844.       transmitted or when a handshaking signal is inhibited. Direct mode
  845.       is ideal for transmit intensive routines such as file transfers, where
  846.       the main task is transmitting data. Otherwise direct transmit mode
  847.       is not normally preferred. 
  848.       
  849.       There are two ways to get into direct transmit mode. The first is to 
  850.       set the transmit queue size in the call to the open function (or 
  851.       constructor in C++) to zero. This method sets direct transmit mode 
  852.       permanently. To set direct transmit mode temporarily, turn the 
  853.       transmitter off with ComTx with the TX_DIRECT option.
  854.  
  855.                                  2-11
  856.  
  857.  
  858.       C Example 1
  859.  
  860.             int main(void)
  861.             {
  862.             COM com;
  863.  
  864.                   /* transmit queue 0 = direct transmit mode
  865.                    */
  866.                com = ComOpen(COM1, B9600, W8 | S1 | NONE, 4096, 0);
  867.                if(com == NULL)
  868.                   return(comopen_errno);
  869.  
  870.                   /* continued   */
  871.  
  872.                ComClose(com);
  873.                return(0);
  874.             }
  875.  
  876.  
  877.  
  878.       C++ Example 1
  879.  
  880.             int main(void)
  881.             {
  882.                   // transmit queue 0 = direct transmit mode
  883.  
  884.                Cport com(COM1, B9600, W8 | S1 | NONE, 4096, 0);
  885.  
  886.                   // continued
  887.  
  888.                return(0);
  889.             }
  890.  
  891.       In this examples, the transmitter is put into direct mode while a
  892.       block of data is transmitted. The transmitter is subsequently
  893.       restored to its previous state. The block of data is completely
  894.       transmitted before the function returns (assumes no transmit
  895.       handshaking is enabled).
  896.  
  897.       C Example 2
  898.  
  899.             #define BLOCK_SIZE   1024
  900.  
  901.             int SendBlock(COM com, byte *block)
  902.             {
  903.             int tx, rv;
  904.  
  905.                tx = ComTx(com, OFF | TX_DIRECT);
  906.                rv = ComOut(com, block, BLOCK_SIZE);
  907.                ComTx(com, tx);
  908.                return(rv);
  909.             }
  910.  
  911.                                  2-12
  912.  
  913.  
  914.       C Example 2
  915.  
  916.             #define BLOCK_SIZE   1024
  917.  
  918.             int SendBlock(Cport& com, byte *block)
  919.             {
  920.             int tx, rv;
  921.  
  922.                tx = com.Tx( OFF | TX_DIRECT);
  923.                rv = com.Out(block, BLOCK_SIZE);
  924.                com.Tx(tx);
  925.                return(rv);
  926.             }
  927.  
  928.  
  929.    Handshaking in Direct Transmit Mode
  930.    -----------------------------------
  931.       Transmit handshaking works a bit differently in direct transmit
  932.       mode. In normal transmit handshaking, output functions will always
  933.       succeed in putting the data as long as there is room in the transmit
  934.       queue, even if transmit handshaking is in an inhibited state. In
  935.       direct transmit mode, there is no transmit queue to buffer the output
  936.       data during the inhibited state of transmit handshaking. Therefore,
  937.       in direct transmit mode, an output function may not complete a
  938.       transmission of the data if transmit handshaking changes to an
  939.       inhibited state. 
  940.       
  941.       The return value of the output functions should always be tested when 
  942.       transmit handshaking is used in direct transmit mode to ensure that all 
  943.       of the data has been transmitted. The return value can subsequently be 
  944.       used to transmit the remaining data when the transmit handshaking 
  945.       returns to an asserted state. This is demonstrated in the following 
  946.       example. In this example, it is assumed that DSR handshaking is enabled 
  947.       and the transmitter is in direct mode.
  948.  
  949.         C Example:
  950.  
  951.             void SendData(COM com, char *buf)
  952.             {
  953.             char *_buf = buf;
  954.  
  955.                while(*_buf != '\0')
  956.                {
  957.                   _buf += ComPuts(com, _buf);
  958.  
  959.                   if(*_buf != '\0')
  960.                      while(!ComStatus(com) & DSR);   /* wait for DSR */
  961.                }
  962.             }
  963.  
  964.                                  2-13
  965.  
  966.  
  967.       C++ Example
  968.  
  969.             void SendData(Cport& com, char *buf)
  970.             {
  971.             char *_buf = buf;
  972.  
  973.                while(*_buf != '\0')
  974.                {
  975.                   _buf += com.Put(_buf);
  976.  
  977.                   if(*_buf != '\0')
  978.                      while(!com.Status() & DSR);   // wait for DSR
  979.                }
  980.             }
  981.  
  982.       Receive handshaking will always function the same regardless of the
  983.       current mode of the transmitter.
  984.  
  985.                                  3-1
  986.  
  987.  
  988. Theory of Operation
  989. ===================
  990.  
  991.    The UART
  992.    --------
  993.       The UART (Universal Asynchronous Receiver/Transmitter) is a single
  994.       integrated circuit peripheral chip, which is specially designed for
  995.       asynchronous serial communications. It is responsible for many of
  996.       the electronic details of serial communications. The UART converts
  997.       parallel data (bytes/characters) to and from serial signals at the
  998.       correct baud rate, and with the assigned word length, stop bits and
  999.       parity. It also monitors and controls the hardware status lines.
  1000.       Cport interfaces intimately with the serial port's UART.
  1001.  
  1002.       The name UART is a generic name used to describe a type of
  1003.       integrated circuit. serial communications in IBM and compatible
  1004.       computers is based on the National Semiconductor family of UARTs.
  1005.       These chips include:
  1006.  
  1007.                               INS8250
  1008.                               INS8250-B
  1009.                               INS8250A
  1010.                               INS82C50A
  1011.                               NS16450
  1012.                               NS16C450
  1013.                               NS16550A
  1014.  
  1015.       The latest and greatest is the NS16550A, which features transmitter
  1016.       and receiver FIFO's. If a NS16550 UART is detected by Cport when a
  1017.       serial port is opened, Cport will automatically take advantage of
  1018.       it's advanced features. These feature greatly improve performance.
  1019.  
  1020.    The Transmitter and Receiver
  1021.    ----------------------------
  1022.       The transmitter and receiver interact intimately with the serial
  1023.       port's UART to coordinate data exchanges between it and the transmit
  1024.       and receive queues. They also coordinate and control any enabled
  1025.       handshaking. The transmitter and receiver together constitute an
  1026.       interrupt service routine that the program will branch to any time
  1027.       the serial port's UART generates an interrupt.
  1028.  
  1029.       When the UART is ready for another byte/character, the transmitter
  1030.       will transfer another byte/character (if available) to the UART. In
  1031.       addition, it sends XON/XOFF characters at the request of the receiver
  1032.       when software handshaking is enabled, and monitors the status of the
  1033.       input hardware lines when hardware handshaking in enables.
  1034.  
  1035.       When the UART receives a new byte/character, the receiver fetches
  1036.       it from the UART and stores it in the receive queue. It also
  1037.       monitors the amount of data in the receive queue when handshaking is
  1038.       enabled, in order to perform the enabled handshaking and avoid a
  1039.       receive queue overflow. In software handshaking, requests to the
  1040.       transmitter are made to send the XON/XOFF characters. In hardware
  1041.       handshaking, the receiver manipulates the  hardware line(s) directly.
  1042.  
  1043.                                  3-2
  1044.  
  1045.  
  1046.    The Transmit and Receive Queues
  1047.    -------------------------------
  1048.       The receive and transmit queues provide the interface/buffering
  1049.       between the Cport input and output functions and the receiver and
  1050.       transmitter respectively. This allows the transmitter/receiver to
  1051.       operate independently from the input/output functions and vice
  1052.       versa. The transmitter is concerned only with the head of the
  1053.       transmit queue while the output functions are only concerned with
  1054.       the tail of the transmit queue. Similarly, the receiver is only
  1055.       concerned with the tail of the receive queue while the input
  1056.       functions are only concerned with the head of the receive queue.
  1057.  
  1058.    Input and Output Functions
  1059.    --------------------------
  1060.       Input functions retrieve data from the receive queue in the order in
  1061.       which it is placed into the receive queue by the receiver. Since the
  1062.       data is buffered, the program does not need to worry about the
  1063.       incoming data until it is ready to fetch it. The output functions
  1064.       insert data into the transmit queue and will be transmitted by the
  1065.       transmitter in the order in which the data is inserted.
  1066.  
  1067.    Control and Status Functions
  1068.    ----------------------------
  1069.       Control functions manipulate both the transmitter/receiver and the
  1070.       UART. The queues are independent of the control functions except
  1071.       when the queues are created and destroyed when the serial port is
  1072.       opened and close respectively. Status functions retrieve information
  1073.       from the transmitter/receiver and the UART. They also manipulate the
  1074.       UART to set status (to the remote unit).
  1075.  
  1076.    Direct Transmit Mode
  1077.    --------------------
  1078.       In direct transmit mode, the transmitter and transmit queue are
  1079.       removed. The output functions write directly to the UART. The output
  1080.       functions will return only after all it's data is written to the
  1081.       UART, or transmit handshaking is enabled and in an inhibited state.
  1082.       This holds up program execution but may be desirable when there are
  1083.       no other tasks to perform, since otherwise, the transmitter and
  1084.       receiver share available background time. An example of when direct
  1085.       transmit mode might be advantageous is a dedicated file transfer
  1086.       routine where the only interest is to transmit data.
  1087.  
  1088.                                  4-1
  1089.  
  1090.  
  1091. C Reference
  1092. ===========
  1093.  
  1094.    Typedefs and Structures
  1095.    -----------------------
  1096.  
  1097.    Basic
  1098.  
  1099.       COM is a typedef used for storing a serial port handle.
  1100.  
  1101.       CPARAM is a structure type used for storing a serial port's parameters.
  1102.  
  1103.       byte is a typedef userd for storing a byte size value.
  1104.  
  1105.                                  4-2
  1106.  
  1107.  
  1108.    COM
  1109.    ------------------------------------------------------------------
  1110.  
  1111.    Function    Data type for storing a serial port handle.
  1112.  
  1113.    Syntax      #include "cport.h"
  1114.                typedef void* COM;
  1115.  
  1116.    Remarks     COM is a type used to store a serial port handle. The open
  1117.                functions (ComOpen and ComOpenS) return values of type COM and
  1118.                all serial port specific functions take a parameter of type COM.
  1119.  
  1120.    Example     Open a serial port.
  1121.  
  1122.                   int main(void)
  1123.                   {
  1124.                   COM com1;
  1125.  
  1126.                      com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
  1127.                      if(com1 == NULL)
  1128.                      {
  1129.                         /* error */
  1130.                      }
  1131.                      ...continued
  1132.  
  1133.    CPARAM
  1134.    ------------------------------------------------------------------
  1135.  
  1136.    Function    Data type for storing a serial port's parameters.
  1137.  
  1138.    Syntax      #include "cport.h"
  1139.                typedef struct
  1140.                {
  1141.                   unsigned   id;
  1142.                   int        baud;
  1143.                   byte       mode;
  1144.                   unsigned   rxQ;
  1145.                   unsigned   txQ;
  1146.                   byte       htype;
  1147.                   unsigned   thresh;
  1148.                }CPARAM;
  1149.  
  1150.       id  -    Value that identifies the serial port. The upper 4 bits define
  1151.                the interrupt request line while the lower 12 bits define the
  1152.                port address. This technique allows for the possibility
  1153.                of custom configurations. See Table A-1 in Appendix A for a list
  1154.                of predefined values.
  1155.  
  1156.       baud   - Value that defines the baud rate. The actual value is the baud
  1157.                rate divisor, which allows for the possibility of custom baud
  1158.                rates. The baud rate divisor = f / (16 * baud rate) where f is
  1159.                1.8432e+6. See Table A-2 in Appendix A for a list of predefined
  1160.                baud rate divisors.
  1161.  
  1162.       mode   - Bit ORed value defining the word length, number of stop bits
  1163.                and the parity. See Table A-3 in Appendix A for a list of mode
  1164.                components.
  1165.                                  4-3
  1166.  
  1167.  
  1168.       * rxQ  - Size, in bytes, of the receive queue.
  1169.  
  1170.       * txQ  - Size in bytes, of the transmit queue.
  1171.  
  1172.                * Limited to 32K in small and medium memory models.
  1173.  
  1174.       htype  - Type of handshaking to be used. See Table A-5 in Appendix A
  1175.                for a list of handshaking components.
  1176.  
  1177.       thresh - Receive queue threshold.
  1178.  
  1179.    Remarks     CPARAM is a structure type that holds the parameters of a
  1180.                serial port. This structure is mainly used with the alternate
  1181.                open function ComOpenS and with the function ComParam.
  1182.  
  1183.    Example     Open COM2 at 9600 baud, 8 bits, 1 stop bit, no parity, a
  1184.                receive queue of 1024 bytes, a transmit queue of 512 bytes and
  1185.                software handshaking (XON/XOFF) with a receive queue threshold of
  1186.                3072 bytes.
  1187.  
  1188.                int main(void)
  1189.                {
  1190.                CPARAM param= {COM2, B9600, W8|S1|NONE, 4096, 512, SOFT, 3072};
  1191.                COM com2;
  1192.  
  1193.                   com2 = ComOpenS(¶m);
  1194.                   if(com2 == NULL)
  1195.                   {
  1196.                      /* error */
  1197.                   }
  1198.  
  1199.                   ...continued
  1200.  
  1201.    byte
  1202.    ------------------------------------------------------------------
  1203.  
  1204.    Function    Data type used for storing byte size values.
  1205.  
  1206.    Syntax      #include "cport.h"
  1207.                typedef unsigned character byte;
  1208.  
  1209.    Remarks     The byte data type is used for storing byte size values. Some
  1210.                of the Cport functions take parameters of type byte and some
  1211.                return values of type byte.
  1212.  
  1213.    Example     Use a byte data type for the mode parameter.
  1214.  
  1215.                static byte mode = W8|S1|NONE;
  1216.  
  1217.                byte Mode(COM terminal, byte newmode)
  1218.                {
  1219.                byte temp;
  1220.  
  1221.                   ComMode(terminal, newmode);
  1222.                   temp = mode;
  1223.                   mode = newmode;
  1224.                   return(temp);      /* return previous mode */
  1225.                }
  1226.                                  4-4
  1227.  
  1228.  
  1229.    Global Variables
  1230.    ----------------
  1231.  
  1232.    comopen_errno
  1233.    ------------------------------------------------------------------
  1234.  
  1235.    Function    Holds the error code from the last attempt to open a serial
  1236.                port.
  1237.  
  1238.    Syntax      #include "cport.h"
  1239.                extern int comopen_errno;
  1240.  
  1241.    Remarks     Comopen_errno holds the error code from the last attempt to
  1242.                open a serial port via a call to ComOpen or ComOpenS. If the
  1243.                last opened serial port was successfully opened, comopen_errno
  1244.                will be 0. If an error occurred while attempting to open the
  1245.                serial port the value of comopen_errno will be non-zero. See
  1246.                Table A-4 in Appendix A for a list of possible values for
  1247.                comopen_errno.
  1248.  
  1249.    Example     Attempt to open COM1. If an error occurs, check comopen_errno
  1250.                for the cause.
  1251.  
  1252.                int main(void)
  1253.                {
  1254.                COM com1;
  1255.  
  1256.                   com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
  1257.                   if(com1 == NULL)
  1258.                   {
  1259.                      switch(comopen_errno)
  1260.                      {
  1261.                         case RX_ALC:
  1262.                         case TX_ALC:
  1263.                         case GEN_ALC:
  1264.                            /* memory allocation error */
  1265.                            break;
  1266.  
  1267.                         case NO_UART:
  1268.                            /* no UART at that address */
  1269.                            break;
  1270.  
  1271.                         default:
  1272.                            /* all other errors */
  1273.                            break;
  1274.                      }
  1275.                   }
  1276.                   ...continued
  1277.  
  1278.                                  4-5
  1279.  
  1280.  
  1281.    Control Functions
  1282.    -----------------
  1283.  
  1284.  
  1285.    Basic
  1286.  
  1287.       ComOpen opens a serial port using discrete parameters.
  1288.  
  1289.       ComOpenS opens a serial port using a structure of parameters.
  1290.  
  1291.       ComClose closes a currently open serial port.
  1292.  
  1293.       ComCloseAll closes all open serial ports.
  1294.  
  1295.       ComHandshake determines if and what type of handshaking scheme will be
  1296.       enabled and sets the receiver threshold.
  1297.  
  1298.  
  1299.    Intermediate
  1300.  
  1301.       ComParam reports on the current parameters and handshaking under which
  1302.       the specified serial port is currently operating.
  1303.  
  1304.       ComBaud changes the serial port's baud rate.
  1305.  
  1306.       ComMode changes the serial port's word length, number of stop bits and
  1307.       parity.
  1308.  
  1309.  
  1310.    Advanced
  1311.  
  1312.       ComRxQ resizes the receive queue.
  1313.  
  1314.       ComTxQ resizes the transmit queue.
  1315.  
  1316.       ComTx allows advanced control over the Cport transmitter.
  1317.  
  1318.       ComNS550 sets the receive fifo threshold of an NS16550 UART.
  1319.  
  1320.       ComTurbo temporarily disables/re-enables selected high priority
  1321.       interrupts that may impede high speed transfers.
  1322.  
  1323.  
  1324.                                  4-6
  1325.  
  1326.  
  1327.    ComOpen
  1328.    ------------------------------------------------------------------
  1329.  
  1330.    Function    Opens a serial port for communications.
  1331.  
  1332.    Syntax      #include "cport.h"
  1333.                COM ComOpen(unsigned id, int baud, byte mode,
  1334.                                           unsigned rxQ, unsigned txQ);
  1335.    Parameters
  1336.  
  1337.       id     - Value that identifies the serial port. The upper 4 bits define
  1338.                the interrupt request line, while the lower 12 bits define the
  1339.                port address. This technique allows for possibility of custom
  1340.                configurations. See Table A-1 in Appendix A for a list of
  1341.                predefined values.
  1342.  
  1343.       baud   - Value that defines the baud rate. The actual value is the baud
  1344.                rate divisor, which allows for the possibility of custom baud
  1345.                rates. The baud rate divisor = f / (16 * baud rate) where f is
  1346.                1.8432e+6. See Table A-2 in Appendix A for a list of predefined
  1347.                baud rate divisors.
  1348.  
  1349.       mode   - Bit ORed value defining the word length, number of stop bits
  1350.                and the parity. See Table A-3 in Appendix A for a list of mode
  1351.                components.
  1352.  
  1353.       * rxQ  - Size, in bytes, of the receive queue.
  1354.  
  1355.       * txQ  - Size, in bytes, of the transmit queue.
  1356.  
  1357.                * Limited to 32K in small and medium memory models.
  1358.  
  1359.    Remarks     ComOpen opens the specified serial port and returns a handle
  1360.                used to identify the newly opened serial port. If ComOpen fails
  1361.                to open the specified serial port, it returns NULL and sets
  1362.                comopen_errno to an error code. The 4 most significant bits in
  1363.                id represent the interrupt vector, while the lower 12 bits
  1364.                represent the port address. Constants are provided in cport.h
  1365.                to facilitate the formulation of the id parameter. The COMx
  1366.                values will work in most cases; however, the IRQx values can
  1367.                be ORed with the PORTx or BIOSx values to produce other
  1368.                combinations. The PORTx values are actual port addresses where
  1369.                the serial ports are normally located. The BIOSx values are
  1370.                actually macros, which fetch the port address from the BIOS data
  1371.                area. Usually the BIOSx and PORTx values will be the same, but
  1372.                it is not guaranteed. Quite often the values at BIOS2 and BIOS3
  1373.                (com 3 and com 4) will be set to 0 regardless if com3 or com4
  1374.                exist. See Table A-1 in Appendix A for a list of predefined
  1375.                values for formulating the id parameter.
  1376.  
  1377.                The parameter baud is the baud rate divisor that determines the 
  1378.                baud rate. Achieving baud rates above 19200 is depends on many 
  1379.                variables such as machine speed, cable length, handshaking 
  1380.                activity, degree bidirectional transfers, number of open serial 
  1381.                ports, the type UART(s) used and activity of other hardware 
  1382.                interrupts.
  1383.  
  1384.                                  4-7
  1385.  
  1386.  
  1387.                The parameter mode determines the word length, number of stop
  1388.                bits and parity. Bits 0 and 1 determine the word length, bit 2
  1389.                determines the number of stop bits, bit 3 enables parity and
  1390.                bits 4 and 5 determine the type of parity check.
  1391.  
  1392.                RxQ and txQ set the size of the receive and transmit queues
  1393.                respectively. RxQ should be at least four times larger than the
  1394.                largest string or block of data the programmer intends to fetch
  1395.                from the queue at once. TxQ can be set as small as 1, but is
  1396.                not recommended. In the small and medium memory models, where
  1397.                all data is limited to 64K, the size queues are limited. In the
  1398.                compact and large memory models, each queue can be as large as
  1399.                64K-1 (65534 bytes).
  1400.  
  1401.    Return value   If successful, ComOpen returns a handle to the newly opened
  1402.                   serial port. In the event of an error, it returns NULL and
  1403.                   sets the global variable comopen_errno to an  error code.
  1404.                   See Table A-4 in Appendix A for a list of possible values
  1405.                   for comopen_errno.
  1406.  
  1407.    See also    ComOpenS, ComClose, ComCloseAll, ComBaud, ComMode, COM,
  1408.                comopen_errno
  1409.  
  1410.    Example     Open COM1 at 9600 baud with 8 bit words, 1 stop bit, no parity,
  1411.                a 1024 byte receiver and a 512 byte transmitter.
  1412.  
  1413.                int main(void)
  1414.                {
  1415.                COM com1;
  1416.  
  1417.                   com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
  1418.                   if(com1 == NULL)
  1419.                   {
  1420.                      switch(comopen_errno)
  1421.                      {
  1422.                         case RX_ALC:
  1423.                         case TX_ALC:
  1424.                         case GEN_ALC:
  1425.                            /* allocation error */
  1426.                            break;
  1427.  
  1428.                         case NO_UART:
  1429.                            /* no UART */
  1430.                            break;
  1431.  
  1432.                         default:
  1433.                            /* all other errors */
  1434.                            break;
  1435.                      }
  1436.                   }
  1437.                   ...continued
  1438.  
  1439.                                  4-8
  1440.  
  1441.  
  1442.    ComOpenS
  1443.    ------------------------------------------------------------------
  1444.  
  1445.    Function    Opens a serial port for communications.
  1446.  
  1447.    Syntax      #include "cport.h"
  1448.                COM ComOpenS(const CPARAM *param);
  1449.  
  1450.    Parameters
  1451.  
  1452.       param  - Pointer to a type CPARAM that contains the serial port
  1453.                parameters.
  1454.  
  1455.    Remarks     ComOpenS is an alternative to ComOpen for opening a serial port.
  1456.                It takes a pointer to a type CPARAM. CPARAM is a structure
  1457.                that contains the serial port parameters.
  1458.  
  1459.    Return value   If successful, ComOpenS returns a handle to the newly opened
  1460.                   serial port. In the event of an error, it returns NULL and
  1461.                   sets the global variable comopen_errno to an error code.
  1462.                   See Table A-4 in Appendix A for a list of possible values
  1463.                   for  comopen_errno.
  1464.  
  1465.    See also    ComOpen, ComClose, ComCloseAll, ComParam, COM, comopen_errno
  1466.  
  1467.    Example     Open COM2 at 9600 baud, 8 bits, 1 stop bit, no parity, a
  1468.                receive queue of 1024 bytes, with a transmit queue of 512
  1469.                bytes and software handshaking (XON/XOFF) with a receive queue
  1470.                threshold of 3072 bytes.
  1471.  
  1472.                int main(void)
  1473.                {
  1474.                CPARAM param = {COM2, B9600, W8|S1|NONE, 4096, 512, SOFT, 3072};
  1475.                COM com2;
  1476.  
  1477.                   com2 = ComOpenS(¶m);
  1478.                   if(com2 == NULL)
  1479.                   {
  1480.                      /* error */
  1481.                   }
  1482.  
  1483.                   ...continued
  1484.  
  1485.  
  1486.    ComClose
  1487.    ------------------------------------------------------------------
  1488.  
  1489.    Function    Closes the specified serial port.
  1490.  
  1491.    Syntax      #include "cport.h"
  1492.                void ComClose(COM);
  1493.  
  1494.    Parameters
  1495.  
  1496.       COM    - Handle of the serial port to be closed.
  1497.  
  1498.                                  4-9
  1499.  
  1500.  
  1501.    Remarks     ComClose closes the specified serial port. Failing to close all
  1502.                serial ports before a program is terminated will cause the
  1503.                system to lock up.
  1504.  
  1505.    See also    ComCloseAll, ComOpen, ComOpenS, COM
  1506.  
  1507.    Example     Close the serial port prior to terminating.
  1508.  
  1509.                int main(void)
  1510.                {
  1511.                COM com1;
  1512.  
  1513.                   com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
  1514.                   if(com1 == NULL)
  1515.                      /* error */
  1516.  
  1517.                   ...later
  1518.  
  1519.                   ComClose(com1);
  1520.                   return(0);
  1521.                }
  1522.  
  1523.    ComCloseAll
  1524.    ------------------------------------------------------------------
  1525.  
  1526.    Function    Closes all currently opened serial ports.
  1527.  
  1528.    Syntax      #include "cport.h"
  1529.                void ComCloseAll(void);
  1530.  
  1531.    Remarks     ComCloseAll closes all the currently opened serial ports.
  1532.                Failing to close all serial ports before a program is
  1533.                terminated will cause the system to lock up. ComCloseAll is
  1534.                convenient for ensuring all serial ports are closed prior to a
  1535.                program's termination.
  1536.  
  1537.    See also    ComClose, ComOpen, ComOpenS
  1538.  
  1539.    Example     Make sure all serial ports are closed prior to terminating.
  1540.  
  1541.                void ErrorExit(void)
  1542.                {
  1543.                   ComCloseAll();
  1544.                   exit(-1);
  1545.                }
  1546.  
  1547.    ComHandshake
  1548.    ------------------------------------------------------------------
  1549.  
  1550.    Function    Enables or disables handshaking (flow control) for the
  1551.                specified serial port.
  1552.  
  1553.    Syntax      #include "cport.h"
  1554.                void ComHandshake(COM, byte htype, unsigned thresh);
  1555.  
  1556.                                  4-10
  1557.  
  1558.  
  1559.  
  1560.    Parameters
  1561.  
  1562.       COM    - Handle of the serial port.
  1563.  
  1564.       htype  - Type of handshaking to be used. See Table A-5 in Appendix A
  1565.                for a list of handshaking components.
  1566.  
  1567.       thresh - Receive queue threshold.
  1568.  
  1569.    Remarks     ComHandshake enables or disables software and/or hardware
  1570.                handshaking for the specified serial port. In software
  1571.                handshaking, XON and XOFF characters are used to suspend and
  1572.                resume communications. Hardware handshaking uses any or all of
  1573.                the DTR, DSR, RTS, CTS and DCD lines to suspend and resume
  1574.                communications. Thresh determines when the receiver will
  1575.                assert or inhibit the corresponding handshaking signals. If
  1576.                no receive handshaking is specified (RTS, DTR or S_RX), the
  1577.                threshold is not used and may be set to zero.
  1578.  
  1579.    See also    ComParam, ComOpenS, ComTx
  1580.  
  1581.    Example     If COM1 is successfully opened, turn on some hardware
  1582.                handshaking and set the receiver threshold to 3/4 of the
  1583.                receiver's full size. The transmitter will not transmit unless
  1584.                both DSR and DCD are asserted. The receiver will inhibit DTR if
  1585.                the receive queue length exceeds the threshold.
  1586.  
  1587.                int main(void)
  1588.                {
  1589.                COM com1;
  1590.  
  1591.                   com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
  1592.                   if(com1 == NULL)
  1593.                   {
  1594.                      /* error */
  1595.                   }
  1596.                   ComHandshake(com1, DSR|DTR|DCD, 768);
  1597.  
  1598.                   ...continued
  1599.  
  1600.                   ComClose(com1);
  1601.                   return(0);
  1602.                }
  1603.  
  1604.    ComParam
  1605.    ------------------------------------------------------------------
  1606.  
  1607.    Function    Retrieves the parameters of the specified serial port.
  1608.  
  1609.    Syntax      #include "cport.h"
  1610.                void ComParam(COM, CPARAM *param);
  1611.  
  1612.    Parameters
  1613.  
  1614.       COM    - Handle of the serial port from which to get the parameters.
  1615.  
  1616.                                  4-11
  1617.  
  1618.  
  1619.       param  - Pointer to a type CPARAM where the parameters will be stored.
  1620.  
  1621.  
  1622.    Remarks     ComParam retrieves the parameters and handshaking status of the
  1623.                specified serial port and stores them in a type CPARAM.
  1624.  
  1625.    See also    CPARAM, ComOpen, ComOpenS, ComMode, ComBaud
  1626.  
  1627.    Example     Open a serial port with the same configuration as one that is
  1628.                already opened.
  1629.  
  1630.                COM ComOpenCopy(unsigned id, COM copyme)
  1631.                {
  1632.                CPARAM param;
  1633.  
  1634.                   ComParam(copyme, ¶m);
  1635.                   param.id = id;
  1636.                   return(ComOpenS(¶m));
  1637.                }
  1638.  
  1639.    ComBaud
  1640.    ------------------------------------------------------------------
  1641.  
  1642.    Function    Changes the baud rate of the specified serial port.
  1643.  
  1644.    Syntax      #include "cport.h"
  1645.                void ComBaud(COM, int baud);
  1646.  
  1647.    Parameters
  1648.  
  1649.       COM    - Handle of the serial port.
  1650.  
  1651.       baud   - Value that defines the baud rate. The actual value is the baud
  1652.                rate divisor, which allows for possibility of custom baud rates.
  1653.                The baud rate divisor = f / (16 * baud rate) where f is
  1654.                1.8432e+6. See Table A-2 in Appendix A for a list of predefined
  1655.                baud rate divisors.
  1656.  
  1657.    Remarks     ComBaud changes the baud rate of the specified serial port. The
  1658.                parameter baud is the baud rate divisor that determines the
  1659.                baud rate.
  1660.  
  1661.    See also    ComOpen, ComOpenS, ComParam, ComMode
  1662.  
  1663.    Example     Set the specified serial port to a new baud rate.
  1664.  
  1665.                                  4-12
  1666.  
  1667.  
  1668.                #define NBAUD   4
  1669.  
  1670.                int SetBaud(COM com, unsigned n)
  1671.                {
  1672.                int baud[NBAUD] = {    B9600, B2400, B1200, B300 };
  1673.  
  1674.                   if(n < NBAUD)
  1675.                   {
  1676.                      ComBaud(com, baud[n]);
  1677.                      return(0);
  1678.                   }
  1679.                   else
  1680.                      return(-1);
  1681.                }
  1682.  
  1683.  
  1684.    ComMode
  1685.    ------------------------------------------------------------------
  1686.  
  1687.    Function    Changes the word length, number of stop bits and parity of the
  1688.                specified serial port.
  1689.  
  1690.    Syntax      #include "cport.h"
  1691.                void ComMode(COM, byte mode);
  1692.  
  1693.    Parameters
  1694.  
  1695.       COM    - Handle of the serial port.
  1696.  
  1697.       mode   - Bit ORed value defining the word length, number of stop bits
  1698.                and the parity. See Table A-3 in Appendix A for a list of mode
  1699.                components.
  1700.  
  1701.    Remarks     ComMode changes the word length, number of stop bits and parity
  1702.                of the specified serial port. The parameter mode determines the
  1703.                word length, number of stop bits and parity of the specified
  1704.                serial port. Bits 0 and 1 determine the word length, bit 2
  1705.                determines the number of stop bits, bit 3 enables parity and
  1706.                bits 4 and 5 determine the type of parity check.
  1707.  
  1708.    See also    ComOpen, ComOpenS, ComParam, ComBaud
  1709.  
  1710.    Example     Set the serial port to a new mode.
  1711.  
  1712.                #define NMODE   2
  1713.  
  1714.                int SetMode(COM com, unsigned n)
  1715.                {
  1716.                byte mode[NMODE] = { W8|S1|NONE, W7|S1|EVEN };
  1717.  
  1718.                   if(n < NMODE)
  1719.                   {
  1720.                      ComMode(com, mode[n]);
  1721.                      return(0);
  1722.                   }
  1723.                   return(-1);
  1724.                }
  1725.                                  4-13
  1726.  
  1727.  
  1728.  
  1729.    ComRxQ
  1730.    ------------------------------------------------------------------
  1731.  
  1732.    Function    Resizes the specified serial port's receive queue.
  1733.  
  1734.    Syntax      #include "cport.h"
  1735.                unsigned ComRxQ(COM, unsigned size);
  1736.  
  1737.    Parameters
  1738.  
  1739.       COM    - Handle of the serial port.
  1740.  
  1741.       size   - New receive queue size.
  1742.  
  1743.  
  1744.    Remarks     ComRxQ resizes the specified serial port's receive queue. The
  1745.                memory currently allocated for the receive queue is freed, and
  1746.                new memory is allocated. If ComRxQ is unable to allocate the
  1747.                specified amount memory, it will try to reallocate memory for
  1748.                the previous size. ComRxQ returns the new queue size. If
  1749.                memory was successfully allocated for the new size, the return
  1750.                value will be size. If the previous size is reallocated, the
  1751.                return value will be the previous size. If no memory could be
  1752.                allocated, ComRxQ returns zero.
  1753.  
  1754.                No data can be received while the new receive queue is being
  1755.                resized. However, data in the transmit queue will continue to
  1756.                be transmitted normally.
  1757.  
  1758.    Return value   ComRxQ returns the new receive queue size.
  1759.  
  1760.    See also    ComTxQ, ComOpen, ComOpenS
  1761.  
  1762.    Example     Enlarge the receive queue for a file transfer.
  1763.  
  1764.                #define LARGE_RX   4096
  1765.                int ReceiveFile(COM com, const char *filename)
  1766.                {
  1767.                CPARAM param;
  1768.  
  1769.                   ComParam(com, ¶m);
  1770.                   if(ComRxQ(com, LARGE_RX) != LARGE_RX)
  1771.                      return(-1);
  1772.  
  1773.                      ... transfer file here
  1774.  
  1775.                      /* Restore original size   */
  1776.                   if(ComRxQ(com, param.rxQ) != param.rxQ)
  1777.                      return(-2);
  1778.                   else
  1779.                      return(0);
  1780.                }
  1781.  
  1782.                                  4-14
  1783.  
  1784.  
  1785.    ComTxQ
  1786.    ------------------------------------------------------------------
  1787.  
  1788.    Function    Resizes the specified serial port's transmit queue.
  1789.  
  1790.    Syntax      #include "cport.h"
  1791.                unsigned ComTxQ(COM, unsigned size);
  1792.  
  1793.    Parameters
  1794.  
  1795.       COM    - Handle of the serial port.
  1796.  
  1797.       size   - New transmit queue size.
  1798.  
  1799.    Remarks     ComTxQ resizes the specified serial port's transmit queue. The
  1800.                memory currently allocated for the transmit queue is freed, and
  1801.                new memory is allocated. If ComTxQ is unable to allocate the
  1802.                specified amount memory, it will try to reallocate memory for
  1803.                the previous size. ComTxQ returns the new queue size. If memory
  1804.                was successfully allocated for the new size, the return value
  1805.                will be size. If the previous size is reallocated, the return
  1806.                value will be the previous size. If no memory could be
  1807.                allocated, ComTxQ returns zero.
  1808.  
  1809.                No data can be transmitted while the new transmit queue is
  1810.                being resized. However, data to the receive queue will
  1811.                continue to be received normally.
  1812.  
  1813.    Return value   ComTxQ returns the new transmit queue size.
  1814.  
  1815.    See also    ComRxQ, ComOpen, ComOpenS
  1816.  
  1817.    Example     Enlarge the transmit queue for a file transfer.
  1818.  
  1819.                #define LARGE_TX   4096
  1820.                int TransmitFile(COM com, const char *filename)
  1821.                {
  1822.                CPARAM param;
  1823.  
  1824.                   ComParam(com, ¶m);
  1825.                   if(ComTxQ(com, LARGE_TX) != LARGE_TX)
  1826.                      return(-1);
  1827.  
  1828.                      ... transfer file here
  1829.  
  1830.                      /* Restore original size   */
  1831.                   if(ComTxQ(com, param.txQ) != param.txQ)
  1832.                      return(-2);
  1833.                   else
  1834.                      return(0);
  1835.                }
  1836.  
  1837.                                  4-15
  1838.  
  1839.  
  1840.    ComTx
  1841.    ------------------------------------------------------------------
  1842.  
  1843.    Function    Transmitter control.
  1844.  
  1845.    Syntax      #include "cport.h"
  1846.                int ComTx(COM, int cmnd);
  1847.  
  1848.    Parameters
  1849.  
  1850.       COM    - Handle of the serial port.
  1851.  
  1852.       cmnd   - Determines the action to be taken on the transmitter See Table
  1853.                A-9 in Appendix A for a list of transmitter options.
  1854.  
  1855.    Remarks     ComTx  allows advanced control of the Cport transmitter The
  1856.                transmitter can be turned on and off to suspend and resume
  1857.                transmissions. This function can be very useful when
  1858.                implementing your own handshaking scheme. In addition, it can
  1859.                inform the output functions to transmit directly when the
  1860.                transmitter is turned off.
  1861.  
  1862.    Return value   ComTx returns the previous status of the transmitter
  1863.  
  1864.    See also    ComHandshake, ComOpenS, ComParam
  1865.  
  1866.    Example     Put a priority character directly  to the  serial port.
  1867.  
  1868.                void PriorityPutc(COM com, char c)
  1869.                {
  1870.                int tx;
  1871.  
  1872.                   tx = ComTx(com, TX_DIRECT | OFF);
  1873.                   ComPutc(com, c);
  1874.                   ComTx(com, tx);   /* restore original state */
  1875.                }
  1876.  
  1877.  
  1878.    ComNS550
  1879.    ------------------------------------------------------------------
  1880.  
  1881.    Function    NS16550 UART setup.
  1882.  
  1883.    Syntax      #include "cport.h"
  1884.                void ComNS550(COM, int trigger);
  1885.  
  1886.    Parameters
  1887.  
  1888.       COM    - Handle of the serial port.
  1889.    trigger   - Trigger threshold for the UART receive fifo. See Table A-12 in
  1890.                Appendix A for a list of trigger thresholds.
  1891.  
  1892.    Remarks     If Cport detects an NS16550 UART when a serial port is opened,
  1893.                Cport automatically takes advantage of it's advanced
  1894.                capabilities.
  1895.  
  1896.                                  4-16
  1897.  
  1898.  
  1899.                The receive fifo threshold is the number of bytes in the
  1900.                receive fifo that will cause an interrupt to be generated. By
  1901.                default, the receive fifo threshold is set  to 14 bytes.
  1902.                ComNS550 allows this receive fifo trigger threshold to be
  1903.                changed.
  1904.  
  1905.    See Also    ComUart
  1906.    Example     If the specified serial port is an NS16550 set the trigger
  1907.                level to 1 byte.
  1908.  
  1909.                void SetThreshIf550(COM com)
  1910.                {
  1911.                   if(ComUart(com) == NS16550)
  1912.                      ComNS550(com, T550_1);
  1913.                }
  1914.  
  1915.    ComTurbo
  1916.    ------------------------------------------------------------------
  1917.  
  1918.    Function    Disables/re-enables high priority interrupts.
  1919.  
  1920.    Syntax      #include "cport.h"
  1921.                void ComTurbo(int options);
  1922.  
  1923.    Parameters
  1924.  
  1925.       options - Bit mask of options. See Table A-6 in Appendix A for possible
  1926.                options.
  1927.  
  1928.    Remarks     During high speed data exchanges, certain events that cause
  1929.                high priority interrupts can inhibit serial communications and
  1930.                possibly cause (over run) errors. This is especially true of
  1931.                the timer, which periodically uses extra time and the
  1932.                keyboard, if keys are pressed.
  1933.  
  1934.                ComTurbo disables selected high priority interrupts or
  1935.                restores all of them. The high priority interrupts should
  1936.                never be disabled permanently or for long periods of time. The
  1937.                timer interrupt is not actually disabled but diverted,
  1938.                allowing the system clock to continue to update. All other
  1939.                options are actually disabled when specified.
  1940.  
  1941.    Example     Disable the keyboard and divert the timer while a block is
  1942.                transferred at high speed.
  1943.  
  1944.                #include <time.h>
  1945.                #define BLK_SZ 128
  1946.  
  1947.                                  4-17
  1948.  
  1949.  
  1950.                int GetBlock(COM com, byte* block, clock_t timeout)
  1951.                {
  1952.                int rv;
  1953.  
  1954.                      /* assume 115200 baud
  1955.                      */
  1956.                   ComTurbo(TIMER | KEYBOARD);
  1957.                   timeout += clock();
  1958.                   while(ComLenRx(com) < BLK_SZ)
  1959.                   {
  1960.                      if(clock() > timeout)
  1961.                      {
  1962.                         ComTurbo(OFF);
  1963.                         return(0);
  1964.                      }
  1965.                   }
  1966.                   rv = ComIn(com, block, BLK_SZ);
  1967.                   ComTurbo(OFF);
  1968.                   return(rv);
  1969.                }
  1970.                                  4-18
  1971.  
  1972.  
  1973.    Input Functions
  1974.    ---------------
  1975.  
  1976.  
  1977.    Basic
  1978.  
  1979.       ComGetc gets a character from the receive queue.
  1980.  
  1981.       ComGets gets a string of characters from the receive.
  1982.  
  1983.       ComIn gets a block of data from the receive queue.
  1984.  
  1985.       ComFlushRx flushes the receive queue and receiver.
  1986.  
  1987.       ComLenRx calculates the number of characters/bytes in the receive queue.
  1988.  
  1989.  
  1990.    Intermediate
  1991.  
  1992.       ComPeek returns a copy of the head character/byte without removing it
  1993.       from the receive queue.
  1994.  
  1995.       ComRxScan scans the receive queue for a specified character.
  1996.  
  1997.                                  4-19
  1998.  
  1999.  
  2000.    ComGetc
  2001.    ------------------------------------------------------------------
  2002.  
  2003.    Function    Fetches a character from the specified serial port's receive
  2004.                queue.
  2005.    Syntax      #include "cport.h"
  2006.                char ComGetc(COM);
  2007.  
  2008.    Remarks     ComGetc fetches the head character from the specified serial
  2009.                port's receive queue. If there are no characters in the
  2010.                receive queue, ComGetc returns a NULL character ('\0').
  2011.  
  2012.    Parameters
  2013.  
  2014.       COM    - Handle of the serial port.
  2015.  
  2016.    Return value   If successful, ComGetc returns the character from the receive 
  2017.                   queue. If it fails, it returns a NULL character ('\0').
  2018.  
  2019.    See also    ComPutc, ComGets, ComIn, ComPeek
  2020.  
  2021.    Example     Get a character from the modem and test if it is a start of
  2022.                header control character.
  2023.  
  2024.                #define SOH 1
  2025.                int CheckForSOH(COM modem)
  2026.                {
  2027.                char c;
  2028.  
  2029.                   c = ComGetc(modem);
  2030.                   return(c == SOH);
  2031.                }
  2032.  
  2033.  
  2034.    ComGets
  2035.    ------------------------------------------------------------------
  2036.    Function    Fetches a string of characters from the specified serial
  2037.                port's receive queue.
  2038.  
  2039.    Syntax      #include "cport.h"
  2040.                char *ComGets(COM, char *str, int maxc, char termc);
  2041.  
  2042.    Parameters
  2043.  
  2044.       COM    - Handle of the serial port.
  2045.       str    - Pointer to the buffer where the string of characters will be
  2046.                stored.
  2047.  
  2048.       maxc   - Maximum number of characters to fetch.
  2049.  
  2050.       termc  - Termination character. ComGets will return if this character
  2051.                is encountered.
  2052.  
  2053.    Remarks     ComGets fetches a string of characters from the specified
  2054.                serial port's receive queue. The string will be stored in str.
  2055.                Str must be at least maxc + 1 characters long to allow for the
  2056.  
  2057.                                  4-20
  2058.  
  2059.  
  2060.                NULL terminator. ComGets will return on the first occurrence
  2061.                of one of three conditions: 1) the character termc is
  2062.                encountered; 2) maxc characters are reached; or 3) no more
  2063.                characters are available in the receive queue.
  2064.  
  2065.    Return value   ComGets returns a pointer to the NULL terminated string.
  2066.  
  2067.    See also    ComPuts, ComGetc, ComIn, ComLenRx
  2068.  
  2069.    Example     Get a measurement from the specified instrument if one is
  2070.                ready.
  2071.  
  2072.                #define MEAS_SIZ   24
  2073.                char* GetMeasurment(COM instrument, char* buf)
  2074.                {
  2075.                   if(ComLenRx(instrument) > MEAS_SIZ)
  2076.                      return(ComGets(instrument, buf, MEAS_SIZ, '\n'));
  2077.  
  2078.                   else
  2079.                      return(NULL);
  2080.                }
  2081.  
  2082.  
  2083.    ComIn
  2084.    ------------------------------------------------------------------
  2085.  
  2086.    Function    Fetches a block of bytes from the specified serial port's
  2087.                receive queue.
  2088.  
  2089.    Syntax      #include "cport.h"
  2090.                unsigned ComIn(COM, void *abyte, unsigned nbyte);
  2091.  
  2092.    Parameters
  2093.  
  2094.       COM    - Handle of the serial port.
  2095.  
  2096.       abyte  - Pointer to a buffer where the block of bytes will be stored.
  2097.  
  2098.       nbyte  - Number of bytes to get from the receive queue.
  2099.  
  2100.    Remarks     ComIn fetches a block of bytes from the specified serial
  2101.                port's the receive queue and stores it in abyte. ComIn will
  2102.                always fetch num_byte bytes unless not enough bytes are
  2103.                available. ComIn is well suited for receiving binary data.
  2104.  
  2105.    Return value   ComIn returns the number of bytes actually fetched.
  2106.  
  2107.    See also    ComOut, ComGetc, ComGets, ComLenRx
  2108.  
  2109.                                  4-21
  2110.  
  2111.  
  2112.    Example     Get a block of 1024 bytes from the serial port.
  2113.  
  2114.                #include <time.h>
  2115.                #define BLK_SZ    1024
  2116.                #define TIMEOUT   -1
  2117.  
  2118.                int GetBlock(COM datalink, byte* buf, clock_t timeout)
  2119.                {
  2120.  
  2121.                   timeout += clock();
  2122.                   while(ComLenRx(datalink) < BLK_SZ)
  2123.                   {
  2124.                      if(clock() > timeout)
  2125.                         return(TIMEOUT);
  2126.                   }
  2127.                   return(ComIn(datalink, buf, BLK_SZ));
  2128.                }
  2129.  
  2130.  
  2131.    ComFlushRx
  2132.    ------------------------------------------------------------------
  2133.  
  2134.    Function    Flushes the specified serial port's receiver and receive
  2135.                queue.
  2136.  
  2137.    Syntax      #include "cport.h"
  2138.                void ComFlushRx(COM);
  2139.  
  2140.    Parameters
  2141.  
  2142.       COM    - Handle of the serial port.
  2143.  
  2144.    Remarks     ComFlushRx deletes the specified serial port's receive queue
  2145.                and the UART of any existing characters/bytes.
  2146.  
  2147.    See also    ComLenRx, ComFlushTx
  2148.  
  2149.    Example     If a receive flush command is in order, flush the receiver.
  2150.  
  2151.                void RemoteCommand(COM com, int command)
  2152.                {
  2153.                   switch(command)
  2154.                   {
  2155.                      case TX_FLUSH:
  2156.                         ComFlushTx(com);
  2157.                         break;
  2158.  
  2159.                      case RX_FLUSH:
  2160.                         ComFlushRx(com);
  2161.                         break;
  2162.  
  2163.                      ...continued
  2164.                   }
  2165.                }
  2166.                                  4-22
  2167.  
  2168.  
  2169.    ComLenRx
  2170.    ------------------------------------------------------------------
  2171.  
  2172.    Function    Calculates the number of characters/bytes in the specified
  2173.                serial port's receive queue.
  2174.  
  2175.    Syntax      #include "cport.h"
  2176.                unsigned ComLenRx(COM);
  2177.  
  2178.    Parameters
  2179.  
  2180.       COM    - Handle of the serial port.
  2181.  
  2182.    Remarks     ComLenRx calculates the number of characters/bytes in the
  2183.                specified serial port's receive queue.
  2184.  
  2185.    Return value   ComLenRx returns the number of characters/bytes residing
  2186.                   in the receive queue.
  2187.  
  2188.    See also    ComFlushRx, ComLenTx
  2189.  
  2190.    Example     Get a measurement from the specified instrument if one is
  2191.                ready.
  2192.  
  2193.                #define MEAS_SIZ   24
  2194.                char* GetMeasurment(COM instrument, char* buf)
  2195.                {
  2196.                   if(ComLenRx(instrument) > MEAS_SIZ)
  2197.                   {
  2198.                      ComGets(instrument, buf, MEAS_SIZ, '\n');
  2199.                      return(buf);
  2200.                   }
  2201.                   else
  2202.                      return(NULL);
  2203.                }
  2204.  
  2205.  
  2206.    ComPeek
  2207.    ------------------------------------------------------------------
  2208.  
  2209.    Function    Fetches a copy of the head character from the specified
  2210.                serial port's receive queue.
  2211.  
  2212.    Syntax      #include "cport.h"
  2213.                char ComPeek(COM);
  2214.  
  2215.    Parameters
  2216.  
  2217.       COM    - Handle of the serial port.
  2218.  
  2219.    Remarks     ComPeek fetches a copy of the head character from the
  2220.                specified serial port's receive queue. ComPeek will not
  2221.                remove the character from the queue.
  2222.  
  2223.    Return value   ComPeek returns the copy of the head character.
  2224.  
  2225.                                  4-23
  2226.  
  2227.  
  2228.    See also    ComGetc, ComRxScan
  2229.  
  2230.  
  2231.    Example     Get the head character, if it is a control character.
  2232.  
  2233.                #include <ctype.h>
  2234.                char GetIfControl(COM com)
  2235.                {
  2236.                char peek;
  2237.  
  2238.                   peek = ComPeek(com);
  2239.  
  2240.                   if(iscntrl(peek))
  2241.                      return(ComGetc(com));
  2242.  
  2243.                   else
  2244.                      return('\0');
  2245.                }
  2246.  
  2247.  
  2248.    ComRxScan
  2249.    ------------------------------------------------------------------
  2250.  
  2251.    Function    Scans the receive queue of the specified serial port for a
  2252.                specific character.
  2253.  
  2254.    Syntax      #include "cport.h"
  2255.                unsigned ComRxScan(COM, char c);
  2256.  
  2257.    Parameters
  2258.  
  2259.       COM    - Handle of the serial port.
  2260.  
  2261.       c      - Character to scan for.
  2262.  
  2263.    Remarks     ComRxScan searches for the character c in the specified serial
  2264.                port's receive queue. If the character is not found, ComRxScan
  2265.                returns a zero. Otherwise it returns the offset into the
  2266.                receive queue of the first occurrence of c starting at 1 for
  2267.                the first character. This is the number of characters that
  2268.                must be fetched to get all data up to and including the
  2269.                character scanned for.
  2270.  
  2271.    Return value   ComRxScan returns the offset into the receive queue to the
  2272.                   first occurrence of c. If c does not exist, ComRxScan
  2273.                   returns a zero.
  2274.  
  2275.    See also    ComPeek
  2276.  
  2277.                                  4-24
  2278.  
  2279.  
  2280.    Example     Get the next line terminated with a '\n'.
  2281.  
  2282.                char *GetLine(COM com, char *buffer)
  2283.                {
  2284.                int n;
  2285.  
  2286.                   n = ComRxScan(com, '\n');
  2287.                   if(n > 0 && n < 80)
  2288.                      return(ComGets(com, buffer, n, '\n'));
  2289.                   else
  2290.                      return(NULL);
  2291.                }
  2292.  
  2293.    Example     Get the next message terminated with a EOT control character.
  2294.  
  2295.                #define EOT   0x4
  2296.  
  2297.                int GetMessage(COM com, byte *buffer)
  2298.                {
  2299.                int n;
  2300.  
  2301.                   n = ComRxScan(com, EOT);
  2302.                   if(n > 0 && n < 80)
  2303.                      return(ComIn(com, buffer, n));
  2304.                   else
  2305.                      return(0);
  2306.                }
  2307.  
  2308.                                  4-25
  2309.  
  2310.  
  2311.    Output Functions
  2312.    ----------------
  2313.  
  2314.  
  2315.    Basic
  2316.  
  2317.       ComPutc puts a character to the transmit queue.
  2318.  
  2319.       ComPuts puts a string of characters to the transmit queue.
  2320.  
  2321.       ComOut puts a block of data to the transmit queue.
  2322.  
  2323.       ComFlushTx flushes the transmit queue and transmitter.
  2324.  
  2325.       ComLenTx calculates the number of characters in the transmit queue.
  2326.  
  2327.  
  2328.    Advanced
  2329.  
  2330.       ComTxWait pauses program execution until the transmitter has emptied.
  2331.  
  2332.                                  4-26
  2333.  
  2334.  
  2335.    ComPutc
  2336.    ------------------------------------------------------------------
  2337.  
  2338.    Function    Puts a character into the specified serial port's transmit
  2339.                queue.
  2340.  
  2341.    Syntax      #include "cport.h"
  2342.                int ComPutc(COM, char c);
  2343.  
  2344.    Parameters
  2345.  
  2346.       COM    - Handle of the serial port.
  2347.  
  2348.       c      - Character to be put into the transmit queue.
  2349.  
  2350.    Remarks     ComPutc puts a character into the specified serial port's
  2351.                transmit queue to be transmitted. If the transmit queue is
  2352.                full, the character is not put and ComPutc returns a 0.
  2353.  
  2354.    Return value   On success, ComPutc returns a 1. If it fails, it returns 0.
  2355.  
  2356.    See also    ComGetc, ComPuts, ComOut
  2357.  
  2358.    Example     Echo the keyboard to the serial port when fetching a keystroke.
  2359.  
  2360.                #include <conio.h>
  2361.  
  2362.                static COM echo;
  2363.  
  2364.                char GetKey(void)
  2365.                {
  2366.                char c;
  2367.  
  2368.                   if(kbhit())
  2369.                   {
  2370.                      c = getch();
  2371.                      ComPutc(echo, c);
  2372.                      return(c);
  2373.                   }
  2374.                   else
  2375.                      return('\0');
  2376.                }
  2377.  
  2378.  
  2379.    ComPuts
  2380.    ------------------------------------------------------------------
  2381.  
  2382.    Function    Puts a string of characters into the specified serial port's
  2383.                transmit queue.
  2384.  
  2385.    Syntax      #include "cport.h"
  2386.                int ComPuts(COM, const char *str);
  2387.  
  2388.                                  4-27
  2389.  
  2390.  
  2391.    Parameters
  2392.  
  2393.       COM    - Handle of the serial port.
  2394.  
  2395.       str    - Pointer to the string to be put into the transmit queue.
  2396.  
  2397.    Remarks     ComPuts puts the string str into the specified serial port's
  2398.                transmit queue to be transmitted. If the transmit queue
  2399.                becomes full, ComPuts will not attempt to put any more
  2400.                characters in the queue.
  2401.  
  2402.    Return value   ComPuts returns the actual number of characters put into
  2403.                   the transmit queue.
  2404.  
  2405.    See also    ComGets, ComPutc, ComOut
  2406.  
  2407.    Example   Dial a number on the modem.
  2408.  
  2409.                #include <string.h>
  2410.  
  2411.                void ModDial(COM modem, const char* number)
  2412.                {
  2413.                char dial[24] = "ATDT";
  2414.  
  2415.                   strcat(dial, number);
  2416.                   strcat(dial, "\r");
  2417.                   ComPuts(modem, dial);
  2418.                }
  2419.  
  2420.  
  2421.    ComOut
  2422.    ------------------------------------------------------------------
  2423.  
  2424.    Function    Puts a block of bytes into the specified serial port's
  2425.                transmit queue.
  2426.  
  2427.    Syntax      #include "cport.h"
  2428.                unsigned ComOut(COM, const void *abyte, unsigned nbyte);
  2429.  
  2430.    Parameters
  2431.  
  2432.       COM    - Handle of the serial port.
  2433.  
  2434.       abyte  - Pointer to the block of data to be put  into the transmit
  2435.                queue.
  2436.  
  2437.       nbyte  - Number of bytes to be put into the transmit  queue.
  2438.  
  2439.    Remarks     ComOut puts the block of bytes pointed to by abyte into the
  2440.                specified serial port's transmit queue to be transmitted.
  2441.  
  2442.    Return value   ComOut returns the number of bytes actually put into the
  2443.                   transmit queue.
  2444.  
  2445.    See also    ComIn, ComPutc, ComPuts
  2446.  
  2447.                                  4-28
  2448.  
  2449.  
  2450.    Example     Send a block of 128 bytes to the transmitter.
  2451.  
  2452.                #define BLK_SZ 128
  2453.                int SendBlock(COM com, const byte* block)
  2454.                {
  2455.                int rv;
  2456.  
  2457.                   rv = ComOut(com, block, BLK_SZ);
  2458.                   if(rv < BLK_SZ)
  2459.                      return(-1);
  2460.  
  2461.                   else
  2462.                      return(0);
  2463.                }
  2464.  
  2465.  
  2466.    ComFlushTx
  2467.    ------------------------------------------------------------------
  2468.  
  2469.    Function    Flushes the specified serial port's transmit queue.
  2470.    Syntax      #include "cport.h"
  2471.                void ComFlushTx(COM);
  2472.  
  2473.    Parameters
  2474.  
  2475.       COM    - Handle of the serial port.
  2476.  
  2477.    Remarks     ComFlushTx deletes any existing characters in the specified
  2478.                serial port's transmit queue.
  2479.  
  2480.    See also    ComFlushRx, ComLenTx
  2481.  
  2482.    Example     If a transmit flush command is in order, flush the transmit
  2483.                queue.
  2484.  
  2485.                void RemoteCommand(COM com, int command)
  2486.                {
  2487.                   switch(command)
  2488.                   {
  2489.                      case TX_FLUSH:
  2490.                         ComFlushTx(com);
  2491.                         break;
  2492.  
  2493.                      case RX_FLUSH:
  2494.                         ComFlushRx(com);
  2495.                         break;
  2496.  
  2497.                      ...continued
  2498.                   }
  2499.                }
  2500.  
  2501.                                  4-29
  2502.  
  2503.  
  2504.    ComLenTx
  2505.    ------------------------------------------------------------------
  2506.  
  2507.    Function    Calculates the number of characters/bytes in the specified
  2508.                serial port's transmit queue.
  2509.  
  2510.    Syntax      #include "cport.h"
  2511.                unsigned ComLenTx(COM);
  2512.  
  2513.    Parameters
  2514.  
  2515.       COM    - Handle of the serial port.
  2516.  
  2517.    Remarks     ComLenTx calculates the number of characters/bytes in the
  2518.                specified serial port's transmit queue.
  2519.  
  2520.    Return value   ComLenTx returns the number of characters/bytes in the
  2521.                   transmit queue.
  2522.  
  2523.    See also    ComLenRx, ComFlushTx
  2524.  
  2525.    Example     Check if the transmitter has reached 3/4 of its capacity.
  2526.  
  2527.                #define TX_SIZE      1024
  2528.  
  2529.                int IsAboveThresh(COM sprinter)
  2530.                {
  2531.                   return(ComLenTx(sprinter) > (TX_SIZE * 3 / 4));
  2532.                }
  2533.  
  2534.  
  2535.    ComTxWait
  2536.    ------------------------------------------------------------------
  2537.  
  2538.    Function    Waits for the specified serial port's transmitter to empty
  2539.  
  2540.    Syntax      #include "cport.h"
  2541.                void ComTxWait(COM);
  2542.  
  2543.    Parameters
  2544.  
  2545.       COM    - Handle of the serial port.
  2546.  
  2547.    Remarks     When a transmit queue becomes empty, the UART may not have
  2548.                actually transmitted the last of the bytes. A program may need
  2549.                to know when all the data has actually been transmitted so
  2550.                that it may, for example, change the state of the hardware
  2551.                lines during half duplex communications. ComTxWait will return
  2552.                after the UART has been emptied of data.
  2553.  
  2554.    See Also    ComLenTx
  2555.  
  2556.                                  4-30
  2557.  
  2558.  
  2559.    Example     Send a string to a half duplex device. This examples assumes
  2560.                that the device is monitoring our RTS line to determine a
  2561.                transmit or receive state.
  2562.  
  2563.                void SendMessage(COM device, const char* msg)
  2564.                {
  2565.                   ComRts(device, ON);
  2566.                   ComPuts(device, msg);
  2567.                   while(ComLenTx(device));
  2568.                   ComTxWait(device);
  2569.                   ComRts(device, OFF);
  2570.                }
  2571.                                  4-31
  2572.  
  2573.  
  2574.    Status Functions
  2575.    ----------------
  2576.  
  2577.  
  2578.    Basic
  2579.  
  2580.       ComError detects hardware and software errors.
  2581.  
  2582.  
  2583.    Intermediate
  2584.  
  2585.       ComStatus returns the status of the software and input hardware lines.
  2586.  
  2587.       ComRts controls the RTS output line.
  2588.  
  2589.       ComDtr controls the DTR output line.
  2590.  
  2591.  
  2592.    Advanced
  2593.  
  2594.       ComOut1 controls the general purpose OUT1 output line.
  2595.  
  2596.       ComUart determines what type of UART chip is residing at a serial port.
  2597.  
  2598.                                  4-32
  2599.  
  2600.  
  2601.    ComError
  2602.    ------------------------------------------------------------------
  2603.  
  2604.    Function    Determines if any errors have occurred on the specified
  2605.                serial port since the last call to ComError.
  2606.  
  2607.    Syntax      #include "cport.h"
  2608.                unsigned ComError(COM);
  2609.  
  2610.    Parameters
  2611.  
  2612.       COM    - Handle of the serial port.
  2613.  
  2614.    Remarks     ComError determines if any errors are pending on the specified
  2615.                serial port. After a call to ComError, the errors are cleared.
  2616.                ComError returns a bit ORed error word. See Table A-7 in
  2617.                Appendix A for a list of bit definitions.
  2618.  
  2619.    Return value   If an error has occurred, ComError returns an error word.
  2620.                   If no errors have occurred, it returns a 0.
  2621.  
  2622.    See also    ComStatus
  2623.  
  2624.    Example     Determine the source of the error if one has occurred.
  2625.  
  2626.                #define HARDWARE   (PARITY | FRAMING | BREAK | RX_FIFO)
  2627.  
  2628.                void CheckForErrors(COM dvm)
  2629.                {
  2630.                unsigned err;
  2631.  
  2632.                   if((err = ComError(dvm)) == 0)
  2633.                      return;
  2634.  
  2635.                   else if(err & OVERUN)
  2636.                   {
  2637.                      /* over run error */
  2638.                   }
  2639.                   else if(err & HARDWARE)
  2640.                   {
  2641.                      /* hardware errors */
  2642.                   }
  2643.                   else if(err & (TXFULL | RXFULL))
  2644.                   {
  2645.                      /* queue errors */
  2646.                   }
  2647.                }
  2648.  
  2649.                                  4-33
  2650.  
  2651.  
  2652.    ComStatus
  2653.    ------------------------------------------------------------------
  2654.  
  2655.    Function    Retrieves the status of the specified serial port's software
  2656.                and hardware lines.
  2657.  
  2658.    Syntax      #include "cport.h"
  2659.                unsigned ComStatus(COM);
  2660.  
  2661.    Parameters
  2662.  
  2663.       COM    - Handle of the serial port.
  2664.  
  2665.    Remarks     ComStatus retrieves the status of the specified serial port's
  2666.                software and hardware lines. ComStatus returns a bit ORed
  2667.                status word. See Table A-8 in Appendix A for a list of bit
  2668.                definitions.
  2669.  
  2670.    Return value   ComStatus returns the status word of the software and
  2671.                   hardware lines.
  2672.  
  2673.    See also    ComError, ComRts, ComDtr
  2674.  
  2675.    Example     Test if the modem is powered up and ready.
  2676.  
  2677.                #include <dos.h>
  2678.  
  2679.                int CheckModem(COM modem)
  2680.                {
  2681.                   ComDtr(modem, ON);
  2682.                   delay(40);
  2683.  
  2684.                   return((ComStatus(modem) & DSR) != 0);
  2685.                }
  2686.  
  2687.  
  2688.    ComRts
  2689.    ------------------------------------------------------------------
  2690.  
  2691.    Function    Asserts or inhibits the specified serial port's Request to
  2692.                Send line.
  2693.  
  2694.    Syntax      #include "cport.h"
  2695.                void ComRts(COM, byte on_off);
  2696.  
  2697.    Parameters
  2698.  
  2699.       COM    - Handle of the serial port.
  2700.  
  2701.       on_off - Determines whether RTS is to be asserted or inhibited. See
  2702.                Table A-10 in Appendix A.
  2703.  
  2704.    Remarks     ComRts asserts or inhibits the specified serial port's RTS
  2705.                line depending on the value of on_off. If the value of on_off
  2706.                is ON, RTS is asserted. If the value of on_off is OFF, RTS is
  2707.                inhibited. In many cases, this signal will be looked at by the
  2708.  
  2709.                                  4-34
  2710.  
  2711.  
  2712.                remote device to determine if it is safe to transmit. This
  2713.                gives the programmer the ability to turn off the remote
  2714.                device's transmitter.
  2715.  
  2716.                NOTE: ComRts should never be called when RTS hardware
  2717.                handshaking is enabled.
  2718.  
  2719.    See also    ComDtr, ComStatus, ComHandshake
  2720.  
  2721.    Example     Put the device in an on or off line state. (Assumes the
  2722.                remote device will not send data without our RTS asserted)
  2723.  
  2724.                void OffLine(COM device)
  2725.                {
  2726.                   ComRts(device, OFF);
  2727.                }
  2728.                void OnLine(COM device)
  2729.                {
  2730.                   ComRts(device, ON);
  2731.                }
  2732.  
  2733.  
  2734.    ComDtr
  2735.    ------------------------------------------------------------------
  2736.  
  2737.    Function    Asserts or inhibits the specified serial port's  Data
  2738.                Terminal Ready line.
  2739.  
  2740.    Syntax      #include "cport.h"
  2741.                void ComDtr(COM, byte on_off);
  2742.  
  2743.    Parameters
  2744.  
  2745.       COM    - Handle of the serial port.
  2746.  
  2747.       on_off - Determines whether DTR is to be asserted or inhibited. See
  2748.                Table A-10 in Appendix A.
  2749.  
  2750.    Remarks     ComDtr asserts or inhibits the specified serial port's DTR
  2751.                line depending on the value of on_off. If the value of on_off
  2752.                is ON, DTR is asserted. If the value of on_off is OFF, DTR is
  2753.                inhibited. In many cases, this signal will be looked at by the
  2754.                remote device to determine if it is safe to transmit. This
  2755.                gives the programmer the ability to turn off the remote
  2756.                device's transmitter.
  2757.  
  2758.                NOTE: ComDtr should never be called when DTR hardware
  2759.                handshaking is enabled.
  2760.  
  2761.    See also    ComRts, ComStatus, ComHandshake
  2762.  
  2763.                                  4-35
  2764.  
  2765.  
  2766.    Example     Put the device in an on or off line state. (Assumes the remote
  2767.                device will not send data without our DTR asserted).
  2768.  
  2769.                void OffLine(COM device)
  2770.                {
  2771.                   ComDtr(device, OFF);
  2772.                }
  2773.                void OnLine(COM device)
  2774.                {
  2775.                   ComDtr(device, ON);
  2776.                }
  2777.  
  2778.  
  2779.    ComOut1
  2780.    ------------------------------------------------------------------
  2781.  
  2782.    Function    Asserts or inhibits the specified serial port's Out1 line.
  2783.  
  2784.    Syntax      #include "cport.h"
  2785.                void ComOut1(COM, byte on_off);
  2786.  
  2787.    Parameters
  2788.  
  2789.       COM    - Handle of the serial port.
  2790.  
  2791.       on_off - Determines whether OUT1 is to be asserted or inhibited. See
  2792.                Table A-10 in Appendix A.
  2793.  
  2794.    Remarks     ComOut1 asserts or inhibits the specified serial port's general
  2795.                purpose OUT1 line depending on the value of on_off. If the
  2796.                value of on_off is ON, OUT1 is asserted. If the value of
  2797.                on_off is OFF, OUT1 is inhibited. OUT1 is a general purpose
  2798.                output sometimes utilized by a device for a special feature
  2799.                or reset.
  2800.  
  2801.    See also    ComRts, ComDtr
  2802.  
  2803.    Example     Reset a smart modem.
  2804.  
  2805.                void SmartReset(COM modem)
  2806.                {
  2807.                   ComOut1(modem, ON);
  2808.                   delay(50);
  2809.                   ComOut1(modem, OFF);
  2810.                }
  2811.  
  2812.  
  2813.    ComUart
  2814.    ------------------------------------------------------------------
  2815.  
  2816.    Function    Determines the type of UART at the specified serial port.
  2817.  
  2818.    Syntax      #include "cport.h"
  2819.                int ComUart(COM);
  2820.  
  2821.                                  4-36
  2822.  
  2823.  
  2824.    Parameters
  2825.  
  2826.       COM    - Handle of the serial port.
  2827.  
  2828.    Remarks     ComUart determines the type of UART chip that resides at the
  2829.                specified serial port. See Table A-11 in Appendix A for a list
  2830.                of UART types.
  2831.  
  2832.    Return value   ComUart returns a value representative of the type of UART
  2833.                   that was detected.
  2834.  
  2835.    See Also    ComNS550
  2836.  
  2837.  
  2838.    Example     If the specified serial port has an NS16550 UART, set the
  2839.                trigger level to 1 byte.
  2840.  
  2841.                void SetThreshIf550(COM com)
  2842.                {
  2843.                   if(ComUart(com) == NS16550)
  2844.                      ComNS550(com, T550_1);
  2845.                }
  2846.                                  4-37
  2847.  
  2848.  
  2849.    Data Integrity
  2850.    --------------
  2851.  
  2852.  
  2853.    Intermediate
  2854.  
  2855.       ComChecksum calculates a byte checksum of a block of data.
  2856.  
  2857.       ComCrc16 calculates a 16 bit cyclic redundancy check (CRC) on a block
  2858.       of data.
  2859.  
  2860.       ComCrc32 calculates a 32 bit cyclic redundancy check (CRC) on a block
  2861.       of data.
  2862.  
  2863.                                  4-38
  2864.  
  2865.  
  2866.    ComChecksum
  2867.    ------------------------------------------------------------------
  2868.  
  2869.    Function    Performs a byte checksum calculation on a block of data.
  2870.  
  2871.    Syntax      #include "cport.h"
  2872.                byte ComChecksum(const void *abyte, unsigned nbyte);
  2873.  
  2874.    Parameters
  2875.  
  2876.       abyte  - Pointer to the block on which the checksum is to be performed.
  2877.  
  2878.       nbyte  - Number of bytes in the block.
  2879.  
  2880.    Remarks     ComChecksum performs a byte checksum on the block of bytes
  2881.                pointed to by abyte. The checksum is calculated by summing all
  2882.                the bytes in the block.
  2883.  
  2884.    Return value   ComChecksum returns a one byte checksum.
  2885.  
  2886.    See also    ComCrc16, ComCrc32, ComIn, ComOut
  2887.  
  2888.    Example     Verify that the actual checksum matches the received checksum.
  2889.  
  2890.                struct Xblock{
  2891.                   byte num;
  2892.                   byte _num;
  2893.                   byte data[128];
  2894.                   byte checksum;
  2895.                }block;
  2896.  
  2897.                int GetXblock(COM com, Xblock *block)
  2898.                {
  2899.                   ComIn(com, block, sizeof(Xblock));
  2900.  
  2901.                   if((ComChecksum(block->data, 128) - block->checksum) != 0)
  2902.                      return(-1);
  2903.                   else
  2904.                      return(0);
  2905.                }
  2906.  
  2907.  
  2908.    ComCrc16
  2909.    ------------------------------------------------------------------
  2910.  
  2911.    Function    Performs a 16 bit cyclic redundancy check on a block of data.
  2912.  
  2913.    Syntax      #include "cport.h"
  2914.                unsigned ComCrc16(const void *abyte, unsigned nbyte);
  2915.  
  2916.    Parameters
  2917.  
  2918.       abyte  - Pointer to the block on which the 16 bit cyclic redundancy
  2919.                check is to be performed.
  2920.  
  2921.       nbyte  - Number of bytes in the block.
  2922.  
  2923.                                  4-39
  2924.  
  2925.  
  2926.    Remarks     ComCrc16 performs a 16 bit cyclic redundancy check on the
  2927.                block of data pointed to by abyte.
  2928.  
  2929.    Return value   ComCrc16 returns the 16 bit CRC value.
  2930.  
  2931.    See also    ComCrc32, ComChecksum, ComIn, ComOut
  2932.  
  2933.    Example     Verify that the actual CRC matches the received CRC.
  2934.  
  2935.                struct Xblock{
  2936.                   byte num;
  2937.                   byte _num;
  2938.                   byte data[128];
  2939.                   unsigned crc;
  2940.                   }block;
  2941.  
  2942.                int GetXblock(COM com, Xblock *block)
  2943.                {
  2944.                   ComIn(com, block, sizeof(Xblock));
  2945.  
  2946.                      /* Check the calculated CRC against the block's CRC.
  2947.                      */
  2948.                   if(ComCrc16(block->data, 128) != block->crc)
  2949.                      return(-1);
  2950.                   else
  2951.                      return(0);
  2952.                }
  2953.  
  2954.  
  2955.    ComCrc32
  2956.    ------------------------------------------------------------------
  2957.  
  2958.    Function    Performs a 32 bit cyclic redundancy check on a block of data.
  2959.  
  2960.    Syntax      #include "cport.h"
  2961.                unsigned long ComCrc32(const void *abyte, unsigned nbyte);
  2962.  
  2963.    Parameters
  2964.  
  2965.       abyte  - Pointer to the block on which the 32 bit cyclic redundancy
  2966.                check is to be performed.
  2967.  
  2968.       nbyte  - Number of bytes in the block.
  2969.  
  2970.    Remarks     ComCrc32 performs a 32 bit cyclic redundancy check on the
  2971.                block of data pointed to by abyte.
  2972.  
  2973.    Return value   ComCrc32 returns the 32 bit CRC value.
  2974.  
  2975.    See also    ComCrc16, ComChecksum, ComIn, ComOut
  2976.  
  2977.                                  4-40
  2978.  
  2979.  
  2980.    Example     Verify that the actual CRC matches the received CRC.
  2981.  
  2982.                struct Packet
  2983.                {
  2984.                   byte num;
  2985.                   byte data[1024];
  2986.                   unsigned long crc;
  2987.                   }packet;
  2988.  
  2989.                int GetBlock(COM com, Packet* packet)
  2990.                {
  2991.                   ComIn(com, packet, sizeof(Packet));
  2992.  
  2993.                      /* Check the calculated CRC against the packet's CRC.
  2994.                      */
  2995.                   if(ComCrc32(packet->data, 1024) != packet->crc)
  2996.                      return(-1);
  2997.                   else
  2998.                      return(0);
  2999.                }
  3000.                                  4-41
  3001.  
  3002.  
  3003.    Misc Functions
  3004.    --------------
  3005.  
  3006.  
  3007.    Advanced
  3008.  
  3009.       ComSetBreak sets a break condition.
  3010.  
  3011.       ComClrBreak clears a break condition.
  3012.  
  3013.       ComPutScrtch writes to the UART's scratch register.
  3014.  
  3015.       ComGetScrtch reads the UART's scratch register.
  3016.  
  3017.                                  4-42
  3018.  
  3019.  
  3020.    ComSetBreak
  3021.    ------------------------------------------------------------------
  3022.  
  3023.    Function    Set a break condition on the specified serial port.
  3024.  
  3025.    Syntax      #include "cport.h"
  3026.                void ComSetBreak(COM);
  3027.  
  3028.    Parameters
  3029.  
  3030.       COM  - Handle of the serial port.
  3031.  
  3032.    Remarks     ComSetBreak sets a break condition on the specified serial
  3033.                port. The break condition will stay in effect until a
  3034.                subsequent call to ComClrBreak is made.
  3035.  
  3036.    See also    ComClrBreak
  3037.  
  3038.    Example     If the an abort condition has been declared, set a break
  3039.                condition. When it clears, release the break condition.
  3040.  
  3041.                void Abort(COM com, int abrt)
  3042.                {
  3043.                static int brkflg;
  3044.  
  3045.                   if(abrt && !brkflg)
  3046.                      ComSetBreak(com);
  3047.  
  3048.                   else if(!abrt && brkflg)
  3049.                      ComClrBreak(com);
  3050.                }
  3051.  
  3052.  
  3053.    ComClrBreak
  3054.    ------------------------------------------------------------------
  3055.  
  3056.    Function    Clears a previously set break condition on the specified
  3057.                serial port.
  3058.  
  3059.    Syntax      #include "cport.h"
  3060.                void ComClrBreak(COM);
  3061.  
  3062.    Parameters
  3063.  
  3064.       COM    - Handle of the serial port.
  3065.  
  3066.    Remarks     ComClrBreak clears a previously set break condition on the
  3067.                specified serial port.
  3068.  
  3069.    See also    ComSetBreak
  3070.                                  4-43
  3071.  
  3072.  
  3073.    Example     If the an abort condition has been declared, set a break
  3074.                condition. When it clears, release the break condition.
  3075.  
  3076.                void Abort(COM com, int abrt)
  3077.                {
  3078.                static int brkflg;
  3079.  
  3080.                   if(abrt && !brkflg)
  3081.                      ComSetBreak(com);
  3082.  
  3083.                   else if(!abrt && brkflg)
  3084.                      ComClrBreak(com);
  3085.                }
  3086.  
  3087.  
  3088.    ComPutScrtch
  3089.    ------------------------------------------------------------------
  3090.  
  3091.    Function    Writes a byte to the specified serial port's scratch register.
  3092.  
  3093.    Syntax      #include "cport.h"
  3094.                void ComPutScrtch(COM, byte abyte);
  3095.  
  3096.    Parameters
  3097.  
  3098.       COM    - Handle of the serial port.
  3099.  
  3100.       abyte  - The byte to be written to the scratch register.
  3101.  
  3102.    Remarks     ComPutScrtch writes the byte value abyte to the specified
  3103.                serial port's UART scratch register. Not all UARTs have a
  3104.                scratch register.
  3105.  
  3106.    See also    ComGetScrtch
  3107.  
  3108.    Example     Exchange a value with the scratch register.
  3109.  
  3110.                byte ScratchExchange(COM com, byte value)
  3111.                {
  3112.                byte rv;
  3113.  
  3114.                   rv = ComGetScrtch(com);   /* read the scratch register */
  3115.                   ComPutScrtch(com, value);   /* write to the scratch register */
  3116.                   return(rv);
  3117.                }
  3118.  
  3119.  
  3120.    ComGetScrtch
  3121.    ------------------------------------------------------------------
  3122.  
  3123.    Function    Fetches the byte stored in the specified serial port's scratch
  3124.                register.
  3125.  
  3126.    Syntax      #include "cport.h"
  3127.                byte ComGetScrtch(COM);
  3128.  
  3129.                                  4-44
  3130.  
  3131.  
  3132.    Parameters
  3133.  
  3134.       COM    - Handle of the serial port.
  3135.  
  3136.    Remarks     ComGetScratch reads the byte in the specified serial port's
  3137.                UART scratch register. Not all UARTs have a scratch register.
  3138.  
  3139.    Return value   ComGetScrtch returns the byte read from the UART scratch
  3140.                   register.
  3141.  
  3142.    See also    ComPutScrtch
  3143.  
  3144.    Example     Exchange a value with the scratch register.
  3145.  
  3146.                byte ScratchExchange(COM com, byte value)
  3147.                {
  3148.                byte rv;
  3149.  
  3150.                   rv = ComGetScrtch(com);   /* read the scratch register */
  3151.                   ComPutScrtch(com, value);   /* write to the scratch register */
  3152.                   return(rv);
  3153.                }
  3154.  
  3155.                                  5-1
  3156.  
  3157.  
  3158. C++ Reference
  3159. =============
  3160.  
  3161.    Control Functions
  3162.    -----------------
  3163.  
  3164.  
  3165.    Basic
  3166.  
  3167.       Cport::Cport constructs serial port instance with either discrete
  3168.       parameters or a structure of parameters.
  3169.  
  3170.       Cport::operator int returns the results of constructing a serial port
  3171.       instance.
  3172.  
  3173.       Cport::Handshake determines if and what type of handshaking scheme
  3174.       will be enabled and sets the receive queue threshold.
  3175.  
  3176.  
  3177.    Intermediate
  3178.  
  3179.       Cport::Param reports on the current parameters and handshaking under
  3180.       which a serial port is currently operating.
  3181.  
  3182.       Cport::Baud changes the baud rate.
  3183.  
  3184.       Cport::Mode changes the word length, number of stop bits and parity.
  3185.  
  3186.  
  3187.    Advanced
  3188.  
  3189.       Cport::RxQ resizes the receive queue.
  3190.  
  3191.       Cport::TxQ resizes the transmit queue.
  3192.  
  3193.       Cport::Tx allows advanced control over the  transmitter.
  3194.  
  3195.       Cport::NS550 sets the receive fifo threshold of an NS16550 UART.
  3196.  
  3197.       Cport::Turbo temporarily disables/re-enables selected high priority
  3198.       interrupts that may impede high speed communications.
  3199.  
  3200.                                  5-2
  3201.  
  3202.  
  3203.    Cport::Cport
  3204.    ------------------------------------------------------------------
  3205.  
  3206.    Function    Constructor.
  3207.  
  3208.    Syntax      #include "cport.h"
  3209.                Cport::Cport(unsigned id, int baud, byte mode = W8|S1|NONE,
  3210.                   unsigned rxQ = 1024, unsigned txQ = 512, byte htype = OFF);
  3211.                or
  3212.  
  3213.                Cport::Cport(unsigned id, int baud, byte mode, unsigned rxQ,
  3214.                                  unsigned txQ, byte htype, unsigned thresh);
  3215.                or
  3216.  
  3217.                Cport::Cport(const CPARAM& param)
  3218.  
  3219.    Parameters
  3220.  
  3221.       id     - Value that identifies the serial port. The upper 4 bits define
  3222.                the interrupt request line, while the lower 12 bits define the
  3223.                port address. This technique allows for possibility of custom
  3224.                configurations. See Table A-1 in Appendix A for a list of
  3225.                predefined values.
  3226.  
  3227.       baud   - Value that defines the baud rate. The actual value is the
  3228.                baud rate divisor, which allows for the possibility of custom
  3229.                baud rates. The baud rate divisor = f / (16 * baud rate) where
  3230.                f is 1.8432e+6. See Table A-2 in Appendix A for a list of
  3231.                predefined baud rate divisors.
  3232.  
  3233.       mode   - Bit ORed value defining the word length, number of stop bits
  3234.                and the parity. See Table A-3 in Appendix A for a list of mode
  3235.                components.
  3236.  
  3237.       * rxQ  - Size, in bytes, of the receive queue.
  3238.  
  3239.       * txQ  - Size, in bytes, of the transmit queue.
  3240.  
  3241.                * Limited to 32K in small and medium memory models.
  3242.  
  3243.       htype  - Type of handshaking to be used. See Table A-5 in Appendix A
  3244.                for a list of handshaking components.
  3245.  
  3246.       thresh - Receive queue threshold.
  3247.  
  3248.    Remarks     The constructor creates an instance of the specified serial
  3249.                port. If the constructor is unable to open the specified
  3250.                serial port, the instance of the serial port will return an
  3251.                error code when casted to an integer. If the port is
  3252.                successfully opened, the instance will return a zero when
  3253.                casted to an integer.
  3254.  
  3255.                The 4 most significant bits in id represent the interrupt
  3256.                vector. The lower 12 bits represent the port address.
  3257.                Constants are provided to facilitate the formulation of the id
  3258.                parameter. The COMx values will work in most cases, however,
  3259.  
  3260.                                  5-3
  3261.  
  3262.  
  3263.                the IRQx values can be ORed with the PORTx or BIOSx values to
  3264.                produce other combinations. The PORTx values are actual port
  3265.                addresses where the serial ports are normally located. The
  3266.                BIOSx values are actually macros, which fetch the port address
  3267.                from the BIOS data area.
  3268.  
  3269.                The parameter baud is the baud rate divisor, that determines
  3270.                the baud rate. Achieving baud rates above 19200 is largely
  3271.                dependent on many variables, such as machine speed, cable
  3272.                length, handshaking activity, degree bidirectional transfers,
  3273.                number of open serial ports, the type UART(s) used and
  3274.                activity of other hardware interrupts.
  3275.  
  3276.                The parameter mode determines the word length, number of stop
  3277.                bits and parity. Bits 0 and 1 determine the word length, bit 2
  3278.                determines the number of stop bits, bit 3 enables parity and
  3279.                bits 4 and 5 determine the type of parity check.
  3280.  
  3281.                RxQ and txQ set the size of the receive and transmit queues
  3282.                respectively. RxQ should be at least 4 times larger than the
  3283.                largest string or block of data expected. TxQ can be set as
  3284.                small as 1, but it is not recommended. In the small and medium
  3285.                memory models where all data is limited to 64K, the size of
  3286.                the queues are limited. In the compact and large memory
  3287.                models, each queue can be as large as 64K -1 (65534 bytes).
  3288.  
  3289.    See Also    Cport::operator int
  3290.  
  3291.    Example     Open COM1 at 9600 baud with 8 bit words, 1 stop bit, no
  3292.                parity, a 1024 byte receiver and a 512 byte transmitter.
  3293.  
  3294.                int main(void)
  3295.                {
  3296.  
  3297.                   Cport com1(COM1, B9600, W8|S1|NONE, 1024, 512);
  3298.                   if((int)com1 != NO_ERR)
  3299.                   {
  3300.                      switch(com1)
  3301.                      {
  3302.                         case RX_ALC:
  3303.                         case TX_ALC:
  3304.                         case GEN_ALC:
  3305.                            // allocation error
  3306.                            break;
  3307.  
  3308.                         case NO_UART:
  3309.                            // no UART
  3310.                            break;
  3311.  
  3312.                         default:
  3313.                            // all other errors
  3314.                            break;
  3315.                      }
  3316.                   }
  3317.                   ...continued
  3318.  
  3319.                                  5-4
  3320.  
  3321.  
  3322.    Cport::operator int
  3323.    ------------------------------------------------------------------
  3324.  
  3325.    Function    Gets the error code from when the instance of the serial port
  3326.                was constructed.
  3327.  
  3328.    Syntax      #include "cport.h"
  3329.                Cport::operator int()
  3330.  
  3331.    Remarks     When an instance of a serial port is constructed, the
  3332.                specified serial port is not necessarily successfully opened.
  3333.                Cport::operator int is an integer typecast used for procuring
  3334.                the error code from when an instance of the serial port was
  3335.                constructed. The actual typecasting may or may not be
  3336.                necessary, but is recommended.
  3337.  
  3338.    Return value   Cport::operator int returns an error code from when the
  3339.                   instance of the serial port was constructed. See Table A-4
  3340.                   in Appendix A for a list of possible return values.
  3341.  
  3342.    See Also    Cport::Cport
  3343.  
  3344.    Example     Check for errors after instance of a serial port is
  3345.                constructed.
  3346.  
  3347.                int main(void)
  3348.                {
  3349.  
  3350.                   Cport com1(COM1, B9600, W8|S1|NONE, 1024, 512);
  3351.  
  3352.                      // The instance 'com1' is casted to an int to procure the
  3353.                      // error code.
  3354.                      //
  3355.                   if((int)com1 != NO_ERR)
  3356.                   {
  3357.                      switch(com1)
  3358.                      {
  3359.                         case RX_ALC:
  3360.                         case TX_ALC:
  3361.                         case GEN_ALC:
  3362.                            // allocation error
  3363.                            break;
  3364.  
  3365.                         case NO_UART:
  3366.                            // no UART
  3367.                            break;
  3368.  
  3369.                         default:
  3370.                            // all other errors
  3371.                            break;
  3372.                      }
  3373.                   }
  3374.                   ...continued
  3375.  
  3376.                                  5-5
  3377.  
  3378.  
  3379.    Cport::Handshake
  3380.    ------------------------------------------------------------------
  3381.  
  3382.    Function    Enables or disables handshaking (flow control ) for a serial
  3383.                port.
  3384.  
  3385.    Syntax      #include "cport.h"
  3386.                void Cport::Handshake(byte htype, unsigned thresh);
  3387.  
  3388.    Parameters
  3389.  
  3390.       htype  - Type of handshaking to be used. See Table A-5 in Appendix A
  3391.                for a list of handshaking components.
  3392.  
  3393.       thresh - Receive queue threshold.
  3394.  
  3395.    Remarks     Cport::Handshake enables or disables software and/or hardware
  3396.                handshaking for the serial port instance. In software
  3397.                handshaking, XON and XOFF characters are used to suspend and
  3398.                resume communications. Hardware handshaking uses any or all of
  3399.                the DTR, DSR, RTS, CTS and DCD lines to suspend and resume
  3400.                communications. Thresh determines when the receiver will
  3401.                assert and inhibit the corresponding handshaking. If no
  3402.                receive handshaking is specified (RTS, DTR or S_RX), the
  3403.                threshold is not used and may be set to zero.
  3404.  
  3405.    See also    Cport::Param, Cport::Cport, Cport::Tx
  3406.  
  3407.    Example     If COM1 is successfully opened, turn on some hardware
  3408.                handshaking and set the receiver threshold to 3/4 of the
  3409.                receiver's full size. The transmitter will not transmit unless
  3410.                both DSR and DCD are asserted. The receiver will inhibit DTR
  3411.                if the receive queue length exceeds the threshold.
  3412.  
  3413.                int main(void)
  3414.                {
  3415.  
  3416.                   Cport com1(COM1, B9600, W8|S1|NONE, 1024, 512);
  3417.                   if((int)com1 != NO_ERR)
  3418.                   {
  3419.                      // error
  3420.                   }
  3421.  
  3422.                   com1.Handshake(DSR|DTR|DCD, 768);
  3423.  
  3424.                   ...continued
  3425.  
  3426.                   return(0);
  3427.                }
  3428.  
  3429.                                  5-6
  3430.  
  3431.  
  3432.    Cport::Param
  3433.    ------------------------------------------------------------------
  3434.  
  3435.    Function    Retrieves the parameters of a serial port.
  3436.  
  3437.    Syntax      #include "cport.h"
  3438.                Cport::Param(CPARAM& param)
  3439.  
  3440.    Parameters
  3441.  
  3442.       param  - Reference to a type CPARAM where the parameters will be
  3443.                stored.
  3444.  
  3445.    Remarks     Cport::Param retrieves the parameters and handshaking status
  3446.                of the serial port instance and stores them in a type CPARAM.
  3447.  
  3448.    See also    CPARAM, Cport::Cport
  3449.  
  3450.    Example     Create an instance of a serial port with the same
  3451.                configuration as one that already exists.
  3452.  
  3453.                Cport OpenCopy(int id, Cport& copyme)
  3454.                {
  3455.                CPARAM param;
  3456.  
  3457.                   copyme.Param(param);
  3458.                   param.id = id;
  3459.                   return(Cport(param));
  3460.                }
  3461.  
  3462.  
  3463.    Cport::Baud
  3464.    ------------------------------------------------------------------
  3465.  
  3466.    Function    Changes the baud rate of a serial port.
  3467.  
  3468.    Syntax      #include "cport.h"
  3469.                void Cport::Baud(int baud);
  3470.  
  3471.    Parameters
  3472.  
  3473.       baud   - Value that defines the baud rate. The actual value is the
  3474.                baud rate divisor, which allows for possibility of custom baud
  3475.                rates. The baud rate divisor = f / (16 * baud rate) where
  3476.                f is 1.8432e+6. See Table A-2 in Appendix A for a list of
  3477.                predefined baud rate divisors.
  3478.  
  3479.    Remarks     Cport::Baud changes the baud rate of the serial port instance.
  3480.                The parameter baud is the baud rate divisor that determines
  3481.                the baud rate.
  3482.  
  3483.    See also    Cport::Cport, Cport::Param, Cport::Mode
  3484.  
  3485.                                  5-7
  3486.  
  3487.  
  3488.    Example     Set the specified serial port to a new baud rate.
  3489.  
  3490.                #define NBAUD   4
  3491.  
  3492.                int SetBaud(Cport& com, unsigned n)
  3493.                {
  3494.                int baud[NBAUD] = { B9600, B2400, B1200, B300 };
  3495.  
  3496.                   if(n < NBAUD)
  3497.                   {
  3498.                      com.Baud(baud[n]);
  3499.                      return(0);
  3500.                   }
  3501.                   else
  3502.                      return(-1);
  3503.                }
  3504.  
  3505.  
  3506.    Cport::Mode
  3507.    ------------------------------------------------------------------
  3508.  
  3509.    Function    Changes the word length, number of stop bits and parity of a
  3510.                serial port.
  3511.  
  3512.    Syntax      #include "cport.h"
  3513.                void Cport::Mode(byte mode);
  3514.  
  3515.    Parameters
  3516.  
  3517.       mode   - Bit ORed value defining the word length, number of stop bits
  3518.                and the parity. See Table A-3 in Appendix A for a list of mode
  3519.                components.
  3520.  
  3521.    Remarks     Cport::Mode changes the word length, number of stop bits and
  3522.                parity of the serial port instance. The parameter mode
  3523.                determines the word length, number of stop bits and parity of
  3524.                the serial port instance. Bits 0 and 1 determine the word
  3525.                length, bit 2 determines the number of stop bits, bit 3 enables
  3526.                parity and bits 4 and 5 determine the type of parity check.
  3527.  
  3528.    See also    Cport::Cport, Cport::Param, Cport::Baud
  3529.  
  3530.    Example     Set the serial port to a new mode.
  3531.  
  3532.                #define NMODE   2
  3533.  
  3534.                int SetMode(Cport& com, unsigned n)
  3535.                {
  3536.                int mode[NMODE] = { W8|S1|NONE, W7|S1|EVEN };
  3537.  
  3538.                   if(n < NMODE)
  3539.                   {
  3540.                      com.Mode(mode[n]);
  3541.                      return(0);
  3542.                   }
  3543.                   return(-1);
  3544.                }
  3545.                                  5-8
  3546.  
  3547.  
  3548.    Cport::RxQ
  3549.    ------------------------------------------------------------------
  3550.  
  3551.    Function    Resizes the receive queue of a serial port.
  3552.  
  3553.    Syntax      #include "cport.h"
  3554.                unsigned Cport::RxQ(unsigned size);
  3555.  
  3556.    Parameters
  3557.  
  3558.       size   - New receive queue size.
  3559.  
  3560.    Remarks     Cport::RxQ resizes the receive queue of the serial port
  3561.                instance. The memory currently allocated for the receive queue
  3562.                is freed and new memory is allocated. If Cport::RxQ is unable
  3563.                to allocate the specified amount memory, it will try to
  3564.                reallocate memory for the previous size. Cport::RxQ returns
  3565.                the new queue size. If memory was successfully allocated for
  3566.                the new size, the return value will be size. If the previous
  3567.                size is reallocated, the return value will be the previous
  3568.                size. If no memory could be allocated, Cport::RxQ returns
  3569.                zero.
  3570.  
  3571.                No data can be received while the new receive queue is being
  3572.                resized. However, data in the transmit queue will continue to
  3573.                be transmitted normally.
  3574.  
  3575.    Return value   Cport::RxQ returns the new receive queue size.
  3576.  
  3577.    See also    Cport::TxQ, Cport::Cport
  3578.  
  3579.    Example     Enlarge the receive queue for a file transfer.
  3580.  
  3581.                #define LARGE_RX   4096
  3582.                int ReceiveFile(Cport& com, const char *filename)
  3583.                {
  3584.                CPARAM param;
  3585.  
  3586.                   com.Param(param);
  3587.                   if(com.RxQ(LARGE_RX) != LARGE_RX)
  3588.                      return(-1);
  3589.  
  3590.                      ... transfer file here
  3591.  
  3592.                      // Restore original size
  3593.                   if(com.RxQ(param.rxQ) != param.rxQ)
  3594.                      return(-2);
  3595.                   else
  3596.                      return(0);
  3597.                }
  3598.  
  3599.                                  5-9
  3600.  
  3601.  
  3602.    Cport::TxQ
  3603.    ------------------------------------------------------------------
  3604.  
  3605.    Function    Resizes the transmit queue of a serial port.
  3606.  
  3607.    Syntax      #include "cport.h"
  3608.                unsigned Cport::TxQ(unsigned size);
  3609.  
  3610.    Parameters
  3611.  
  3612.       size   - New transmit queue size.
  3613.  
  3614.    Remarks     Cport::TxQ resizes the transmit queue of the serial port
  3615.                instance. The memory currently allocated for the transmit
  3616.                queue is freed and new memory is allocated. If Cport::TxQ is
  3617.                unable to allocate the specified amount memory, it will try
  3618.                to reallocate memory for the previous size. Cport::TxQ returns
  3619.                the new queue size. If memory was successfully allocated for
  3620.                the new size, the return value will be size. If the previous
  3621.                size is reallocated, the return value will be the previous
  3622.                size. If no memory could be allocated, Cport::TxQ returns zero.
  3623.  
  3624.                No data can be transmitted while the new transmit queue is
  3625.                being resized. However, data in the receive queue will
  3626.                continue to be received normally.
  3627.  
  3628.    Return value   ComTxQ returns the new transmit queue size.
  3629.  
  3630.    See also    Cport::RxQ, Cport::Cport
  3631.  
  3632.    Example     Enlarge the transmit queue for a file transfer.
  3633.  
  3634.                #define LARGE_TX   4096
  3635.                int TransmitFile(Cport& com, const char *filename)
  3636.                {
  3637.                CPARAM param;
  3638.  
  3639.                   com.Param(param);
  3640.                   if(com.TxQ(LARGE_TX) != LARGE_TX)
  3641.                      return(-1);
  3642.  
  3643.                      ... transfer file here
  3644.  
  3645.                      // Restore original size
  3646.                   if(com.TxQ(param.txQ) != param.txQ)
  3647.                      return(-2);
  3648.                   else
  3649.                      return(0);
  3650.                }
  3651.  
  3652.                                  5-10
  3653.  
  3654.  
  3655.    Cport::Tx
  3656.    ------------------------------------------------------------------
  3657.  
  3658.    Function    Transmitter control.
  3659.  
  3660.    Syntax      #include "cport.h"
  3661.                int Cport::Tx(int cmnd);
  3662.  
  3663.    Parameters
  3664.  
  3665.       cmnd   - Determines the action to be taken on the transmitter See
  3666.                Table A-9 in Appendix A for a list of transmitter options.
  3667.  
  3668.    Remarks     Cport::Tx  allows advanced control of the Cport transmitter
  3669.                The transmitter can be turned off and on to suspend and resume
  3670.                transmissions. This function can be very useful when
  3671.                implementing your own handshaking scheme. In addition, it can
  3672.                inform the output functions to transmit directly when the
  3673.                transmitter is turned off.
  3674.  
  3675.    Return value   Cport::Tx returns the previous status of the transmitter.
  3676.  
  3677.    See also    Cport::Handshake, Cport::Cport, Cport::Param
  3678.  
  3679.    Example     Put a priority character directly  to the  serial port.
  3680.  
  3681.                void PriorityPutc(Cport& com, char c)
  3682.                {
  3683.                int tx;
  3684.  
  3685.                   tx = com.Tx(TX_DIRECT | OFF);
  3686.                   com.Put(c);
  3687.                   com.Tx(tx);
  3688.                }
  3689.  
  3690.  
  3691.    Cport::NS550
  3692.    ------------------------------------------------------------------
  3693.  
  3694.    Function    NS16550 UART setup.
  3695.  
  3696.    Syntax      #include "cport.h"
  3697.                void Cport::NS550(int trigger);
  3698.  
  3699.    Parameters
  3700.  
  3701.       trigger - Trigger threshold for the UART receive fifo. See Table A-12
  3702.                in Appendix A for a list of trigger levels.
  3703.  
  3704.    Remarks     If Cport detects an NS16550 UART when a serial port is opened,
  3705.                Cport automatically takes advantage of it's advanced capabilities.
  3706.  
  3707.                The receive fifo threshold is the number of bytes in the receive
  3708.                fifo that will cause an interrupt to be generated. By default,
  3709.                the receive fifo threshold is set to 14 bytes. Cport::NS550
  3710.                allows this receive fifo trigger threshold to be changed.
  3711.  
  3712.                                  5-11
  3713.  
  3714.  
  3715.    See Also    Cport::Uart
  3716.  
  3717.    Example     If the specified serial port is an NS16550, set the trigger
  3718.                level to 1 byte.
  3719.  
  3720.                void SetThreshIf550(Cport& com)
  3721.                {
  3722.                   if(com.Uart() == NS16550)
  3723.                      com.NS550(T550_1);
  3724.                }
  3725.  
  3726.  
  3727.  
  3728.    Cport::Turbo
  3729.    ------------------------------------------------------------------
  3730.  
  3731.    Function    Disables/re-enables high priority interrupts.
  3732.  
  3733.    Syntax      #include "cport.h"
  3734.                static void Cport::Turbo(int options);
  3735.  
  3736.    Parameters
  3737.  
  3738.       options - Bit mask of options. See Table A-6 in Appendix A for a list
  3739.                of turbo options.
  3740.  
  3741.    Remarks     During high speed data exchanges certain events that cause
  3742.                high priority interrupts can impede serial communications and
  3743.                possibly cause (over run) errors. This is especially true of
  3744.                the timer, which periodically uses extra time, and the
  3745.                keyboard, if keys are pressed.
  3746.  
  3747.                Cport::Turbo disables selected high priority interrupts or
  3748.                restores all of them. The high priority interrupts should
  3749.                never be disabled permanently or for long periods of time. The
  3750.                timer interrupt is not actually disabled but divert, allowing
  3751.                the system clock to continue to update. All other options are
  3752.                actually disabled when specified. Cport::Turbo is a static
  3753.                function. Although not very useful, it can be called prior to
  3754.                and/or independent of any instance of a serial port by
  3755.                specifying it's full name: Cport::Turbo(options).
  3756.  
  3757.    Example     Disable the keyboard and divert the timer while a block is
  3758.                transferred at high speed.
  3759.  
  3760.                                  5-12
  3761.  
  3762.  
  3763.                #include <time.h>
  3764.                #define BLK_SZ 128
  3765.  
  3766.                int GetBlock(Cport& com, byte* block, clock_t timeout)
  3767.                {
  3768.                int rv;
  3769.  
  3770.                      // assume 115200 baud
  3771.                      //
  3772.                   com.Turbo(TIMER | KEYBOARD);
  3773.                   timeout += clock();
  3774.                   while(com.LenRx() < BLK_SZ)
  3775.                   {
  3776.                      if(clock() > timeout)
  3777.                      {
  3778.                         com.Turbo(OFF);
  3779.                         return(0);
  3780.                      }
  3781.                   }
  3782.                   rv = com.In(block, BLK_SZ);
  3783.                   com.Turbo(OFF);
  3784.                   return(rv);
  3785.                }
  3786.                                  5-13
  3787.  
  3788.  
  3789.    Input Functions
  3790.    ---------------
  3791.  
  3792.    Basic
  3793.  
  3794.       Cport::Get gets a character or string of characters from the receive
  3795.       queue.
  3796.  
  3797.       Cport::In gets a block of data from the receive queue.
  3798.  
  3799.       Cport::FlushRx flushes the receive queue and receiver.
  3800.  
  3801.       Cport::LenRx calculates the number of characters/bytes in the receive
  3802.       queue.
  3803.  
  3804.  
  3805.    Intermediate
  3806.  
  3807.       Cport::Peek returns a copy of the head character/byte without removing
  3808.       it from the receive queue.
  3809.  
  3810.       Cport::RxScan scans the receive queue for a specified character.
  3811.  
  3812.                                  5-14
  3813.  
  3814.  
  3815.    Cport::Get
  3816.    ------------------------------------------------------------------
  3817.  
  3818.    Function    Fetches a character or string of characters from a serial
  3819.                port's receive queue.
  3820.  
  3821.    Syntax      #include "cport.h"
  3822.                char* Cport::Get(char *str, int maxc, char termc = '\n');
  3823.  
  3824.                or
  3825.  
  3826.                char Cport::Get();
  3827.  
  3828.    Parameters
  3829.  
  3830.       str    - Pointer to the buffer where the string of characters will be
  3831.                stored.
  3832.  
  3833.       maxc   - Maximum number of characters to fetch.
  3834.  
  3835.       termc  - Termination character. Cport::Get will return if this
  3836.                character is encountered.
  3837.  
  3838.    Remarks     Cport::Get fetches a character or string of characters from
  3839.                the serial port instance's receive queue.
  3840.  
  3841.                If Cport::Get is called with no parameters, it will fetch one
  3842.                character from the head of the serial port instance's receive
  3843.                queue. If there are no characters in the receive queue,
  3844.                Cport::Get returns a NULL character ('\0').
  3845.  
  3846.                If Cport::Get is called with parameters, it fetches a string
  3847.                of characters from the serial port instance's receive queue.
  3848.                The string will be stored in str. Str must be at least
  3849.                maxc + 1 characters long to allow for the NULL terminator.
  3850.                Cport::Get will return on the first occurrence of one of
  3851.                three conditions: 1) the character termc is encountered;
  3852.                2) maxc characters are reached; or 3) no more characters are
  3853.                available in the receive queue.
  3854.  
  3855.    Return value   When Cport:Get is called with no parameters, on success
  3856.                   it returns the character from the receive queue. If it
  3857.                   fails, it returns a NULL character ('\0'). When it is called
  3858.                   with parameters, Cport::Get returns a pointer to the NULL
  3859.                   terminated string.
  3860.  
  3861.    See also    Cport::In, Cport::LenRx, Cport::Put
  3862.  
  3863.                                  5-15
  3864.  
  3865.  
  3866.    Example     Get a measurement from the specified instrument if one is
  3867.                ready.
  3868.  
  3869.                #define MEAS_SIZ   24
  3870.                char* GetMeasurment(Cport& instrument, char* buf)
  3871.                {
  3872.                   if(instrument.LenRx() > MEAS_SIZ)
  3873.                   {
  3874.                      instrument.Get(buf, MEAS_SIZ, '\n');
  3875.                      return(buf);
  3876.                   }
  3877.                   else
  3878.                      return(NULL);
  3879.                }
  3880.  
  3881.    Example     Get a character from the modem and test if it is a start of
  3882.                header control character.
  3883.  
  3884.                #define SOH 1
  3885.                int CheckForSOH(Cport& modem)
  3886.                {
  3887.                char c;
  3888.  
  3889.                   c = modem.Get();
  3890.                   return(c == SOH);
  3891.                }
  3892.  
  3893.  
  3894.    Cport::In
  3895.    ------------------------------------------------------------------
  3896.  
  3897.    Function    Fetches a block of bytes from a serial port's receive queue.
  3898.  
  3899.    Syntax      #include "cport.h"
  3900.                unsigned Cport::In(void *abyte, unsigned nbyte);
  3901.  
  3902.    Parameters
  3903.  
  3904.       abyte  - Pointer to a buffer where the block of bytes will be stored.
  3905.  
  3906.       nbyte  - Number of bytes to get from the receive queue.
  3907.  
  3908.    Remarks     Cport::In fetches a block of bytes from the serial port
  3909.                instance's receive queue and stores it in abyte. Cport::In
  3910.                will always fetch num_byte bytes unless not enough bytes are
  3911.                available. Cport::In is well suited for receiving binary data.
  3912.  
  3913.    Return value   Cport::In returns the number of bytes actually fetched.
  3914.  
  3915.    See also    Cport::Out, Cport::Get, Cport::LenRx
  3916.  
  3917.                                  5-16
  3918.  
  3919.  
  3920.    Example     Get a block of 1024 bytes from the serial port.
  3921.  
  3922.                #include <time.h>
  3923.                #define BLK_SZ    1024
  3924.                #define TIMEOUT   -1
  3925.  
  3926.                int GetBlock(Cport& datalink, byte* buf, clock_t timeout)
  3927.                {
  3928.  
  3929.                   timeout += clock();
  3930.                   while(datalink.LenRx() < BLK_SZ)
  3931.                   {
  3932.                      if(clock() > timeout)
  3933.                         return(TIMEOUT);
  3934.                   }
  3935.                   return(datalink.In(buf, BLK_SZ));
  3936.                }
  3937.  
  3938.  
  3939.    Cport::FlushRx
  3940.    ------------------------------------------------------------------
  3941.  
  3942.    Function    Flushes a serial port's receiver and receive queue.
  3943.  
  3944.    Syntax      #include "cport.h"
  3945.                void Cport::FlushRx();
  3946.  
  3947.    Remarks     Cport::FlushRx deletes all existing characters/bytes in the
  3948.                serial port instance's receive queue and receiver.
  3949.  
  3950.    See also    Cport::LenRx, Cport::FlushTx
  3951.  
  3952.    Example     If a receive flush command is in order, flush the receiver.
  3953.  
  3954.                void RemoteCommand(Cport& com, int command)
  3955.                {
  3956.                   switch(command)
  3957.                   {
  3958.                      case TX_FLUSH:
  3959.                         com.FlushTx();
  3960.                         break;
  3961.  
  3962.                      case RX_FLUSH:
  3963.                         com.FlushRx();
  3964.                         break;
  3965.  
  3966.                      ...continued
  3967.                   }
  3968.                }
  3969.  
  3970.                                  5-17
  3971.  
  3972.  
  3973.    Cport::LenRx
  3974.    ------------------------------------------------------------------
  3975.  
  3976.    Function    Calculates the number of characters/bytes in the receive
  3977.                queue of a serial port.
  3978.  
  3979.    Syntax      #include "cport.h"
  3980.                unsigned Cport::LenRx();
  3981.  
  3982.    Remarks     Cport::LenRx calculates the number of characters/bytes
  3983.                in the receive queue of the serial port instance.
  3984.  
  3985.    Return value   Cport::LenRx returns the number of characters/bytes
  3986.                   residing in the receive queue.
  3987.  
  3988.    See also    Cport::FlushRx, Cport::LenTx
  3989.  
  3990.    Example     Get a measurement from the specified instrument if one is
  3991.                ready.
  3992.  
  3993.                #define MEAS_SIZ   24
  3994.                char* GetMeasurment(Cport& instrument, char* buf)
  3995.                {
  3996.                   if(instrument.LenRx() > MEAS_SIZ)
  3997.                   {
  3998.                      instrument.Get(buf, MEAS_SIZ, '\n');
  3999.                      return(buf);
  4000.                   }
  4001.                   else
  4002.                      return(NULL);
  4003.                }
  4004.  
  4005.  
  4006.    Cport::Peek
  4007.    ------------------------------------------------------------------
  4008.  
  4009.    Function    Fetches a copy of the head character from a serial port's
  4010.                receive queue.
  4011.  
  4012.    Syntax      #include "cport.h"
  4013.                char Cport::Peek();
  4014.  
  4015.    Remarks     Cport::Peek fetches a copy of the head character from the
  4016.                serial port instance's receive queue. Cport::Peek will not
  4017.                remove the character from the queue.
  4018.  
  4019.    Return value   Cport::Peek returns the copy of the head character.
  4020.  
  4021.    See also    Cport::Get, Cport::RxScan
  4022.  
  4023.                                  5-18
  4024.  
  4025.  
  4026.    Example     Get the head character if it is a control character.
  4027.  
  4028.                #include <ctype.h>
  4029.                char GetIfControl(Cport& com)
  4030.                {
  4031.                char peek;
  4032.  
  4033.                   peek = com.Peek();
  4034.                   if(iscntrl(peek))
  4035.                      return(com.Get());
  4036.                   else
  4037.                      return('\0');
  4038.                }
  4039.  
  4040.  
  4041.    Cport::RxScan
  4042.    ------------------------------------------------------------------
  4043.  
  4044.    Function    Scans the receive queue of a serial port for a specific
  4045.                character.
  4046.  
  4047.    Syntax      #include "cport.h"
  4048.                unsigned Cport::RxScan(char c);
  4049.  
  4050.    Parameters
  4051.  
  4052.       c      - Character to scan for.
  4053.  
  4054.    Remarks     Cport::RxScan searches for the character c in the serial port
  4055.                instance's receive queue. If the character is not found,
  4056.                Cport::RxScan returns a zero. Otherwise, it returns the offset
  4057.                into the receive queue of the first occurrence of c starting
  4058.                at 1 for the head character. This is the number of characters
  4059.                that must be fetched to get all data up to and including the
  4060.                character scanned for.
  4061.  
  4062.    Return value   Cport::Peek returns the offset into the receive queue to
  4063.                   the first occurrence of c. If c does not exist,
  4064.                   Cport::RxScan returns a zero.
  4065.  
  4066.    See also    Cport::Peek, Cport::Get
  4067.  
  4068.    Example     Get the next line terminated with a '\n'.
  4069.  
  4070.                char *GetLine(Cport& com, char *buffer)
  4071.                {
  4072.                int n;
  4073.  
  4074.                   n = com.RxScan('\n');
  4075.                   if(n > 0 && n < 80)
  4076.                      return(com.Get(buffer, n, '\n'));
  4077.                   else
  4078.                      return(NULL);
  4079.                }
  4080.                                  5-19
  4081.  
  4082.  
  4083.    Output Functions
  4084.    ----------------
  4085.  
  4086.  
  4087.    Basic
  4088.  
  4089.       Cport::Put puts a  character or a string of characters to the transmit
  4090.       queue.
  4091.  
  4092.       Cport::Out puts a block of data to the transmit queue.
  4093.  
  4094.       Cport::FlushTx flushes the transmit queue and transmitter.
  4095.  
  4096.       Cport::LenTx calculates the number of characters/bytes in the transmit
  4097.       queue.
  4098.  
  4099.  
  4100.    Advanced
  4101.  
  4102.       Cport::TxWait pauses program execution until the transmitter has emptied.
  4103.  
  4104.                                  5-20
  4105.  
  4106.  
  4107.    Cport::Put
  4108.    ------------------------------------------------------------------
  4109.  
  4110.    Function    Puts a character or a string of characters into the serial
  4111.                port's transmit queue.
  4112.  
  4113.    Syntax      #include "cport.h"
  4114.                int Cport::Put(const char *str);
  4115.  
  4116.                or
  4117.  
  4118.                int Cport::Put(char c);
  4119.  
  4120.    Parameters
  4121.  
  4122.       str    - Pointer to the string to be put into the transmit queue.
  4123.  
  4124.       c      - Character to be put into the transmit queue.
  4125.  
  4126.    Remarks     Cport::Put puts a character (c) or a string of characters
  4127.                (str) into the serial port a instance's transmit queue to be
  4128.                transmitted. If the transmit queue becomes full, Cport::Put
  4129.                will not attempt to put any more characters in the queue.
  4130.  
  4131.    Return value   Cport::Put returns the actual number of characters put
  4132.                   into the transmit queue. For single characters, this value
  4133.                   will be either 0 or 1.
  4134.  
  4135.    See also   Cport::Out, Cport::Get, Cport::LenTx
  4136.  
  4137.    Example     Echo the keyboard to the serial port when fetching a
  4138.                keystroke.
  4139.  
  4140.                #include <conio.h>
  4141.  
  4142.                static Cport echo(COM2, B9600, W8|S1|NONE ,1024 , 64);
  4143.  
  4144.                char GetKey(void)
  4145.                {
  4146.                char c;
  4147.  
  4148.                   if(kbhit())
  4149.                   {
  4150.                      c = getch();
  4151.                      echo.Put(c);
  4152.                      return(c);
  4153.                   }
  4154.                   else
  4155.                      return('\0');
  4156.                }
  4157.  
  4158.                                  5-21
  4159.  
  4160.  
  4161.    Example   Dial a number on the modem.
  4162.  
  4163.                #include <string.h>
  4164.  
  4165.                void ModDial(Cport& modem, const char* number)
  4166.                {
  4167.                char dial[24] = "ATDT";
  4168.  
  4169.                   strcat(dial, number);
  4170.                   strcat(dial, "\r");
  4171.                   modem.Put(dial);
  4172.                }
  4173.  
  4174.  
  4175.    Cport::Out
  4176.    ------------------------------------------------------------------
  4177.  
  4178.    Function    Puts a block of bytes into a serial port's transmit queue.
  4179.  
  4180.    Syntax      #include "cport.h"
  4181.                unsigned Cport::Out(const void *abyte, unsigned nbyte);
  4182.  
  4183.    Parameters
  4184.  
  4185.       abyte  - Pointer to the block to be put into the transmit queue.
  4186.  
  4187.       nbyte  - Number of bytes to be put into the transmit  queue.
  4188.  
  4189.    Remarks     Cport::Out puts the block of bytes pointed to by abyte into
  4190.                the serial port instance's transmit queue to be transmitted.
  4191.  
  4192.    Return value   Cport::Out returns the number of bytes actually put into
  4193.                   the transmit queue.
  4194.  
  4195.    See also    Cport::In, Cport::Put, Cport::LenTx
  4196.  
  4197.    Example     Send a block of 128 bytes to the transmitter.
  4198.  
  4199.                #define BLK_SZ 128
  4200.                int SendBlock(Cport& com, byte* block)
  4201.                {
  4202.                int rv;
  4203.  
  4204.                   rv = com.Out(block, BLK_SZ);
  4205.                   if(rv < BLK_SZ)
  4206.                      return(-1);
  4207.  
  4208.                   else
  4209.                      return(0);
  4210.                }
  4211.  
  4212.                                  5-22
  4213.  
  4214.    Cport::FlushTx
  4215.    ------------------------------------------------------------------
  4216.  
  4217.    Function    Flushes a serial port's transmit queue.
  4218.  
  4219.    Syntax      #include "cport.h"
  4220.                void Cport::FlushTx();
  4221.  
  4222.    Remarks     Cport::FlushTx deletes any existing characters in the serial
  4223.                port instance's transmit queue.
  4224.  
  4225.    See also    Cport::FlushRx, Cport::LenTx
  4226.  
  4227.    Example     If a transmit flush command is in order, flush the transmit
  4228.                queue.
  4229.  
  4230.                void RemoteCommand(Cport& com, int command)
  4231.                {
  4232.                   switch(command)
  4233.                   {
  4234.                      case TX_FLUSH:
  4235.                         com.FlushTx();
  4236.                         break;
  4237.  
  4238.                      case RX_FLUSH:
  4239.                         com.FlushRx();
  4240.                         break;
  4241.  
  4242.                      ...continued
  4243.                   }
  4244.                }
  4245.  
  4246.  
  4247.    Cport::LenTx
  4248.    ------------------------------------------------------------------
  4249.  
  4250.    Function    Calculates the number of characters/bytes in a serial
  4251.                port's transmit queue.
  4252.  
  4253.    Syntax      #include "cport.h"
  4254.                unsigned Cport::LenTx();
  4255.  
  4256.    Remarks     Cport::LenTx calculates the number of characters/bytes
  4257.                in the serial port instance's transmit queue.
  4258.  
  4259.    Return value   Cport::LenTx returns the number of characters/bytes
  4260.                   in the transmit queue.
  4261.  
  4262.    See also    Cport::LenRx, Cport::FlushTx
  4263.  
  4264.    Example     Check if the transmitter has reached 3/4 of capacity.
  4265.  
  4266.                #define TX_SIZE      1024
  4267.  
  4268.                int IsAboveThresh(Cport& sprinter)
  4269.                {
  4270.                   return(sprinter.LenTx() > (TX_SIZE * 3 / 4));
  4271.                }
  4272.                                  5-23
  4273.  
  4274.  
  4275.    Cport::TxWait
  4276.    ------------------------------------------------------------------
  4277.  
  4278.    Function    Waits for a serial port's transmitter to empty
  4279.  
  4280.    Syntax      #include "cport.h"
  4281.                void Cport::TxWait();
  4282.  
  4283.    Remarks     When a transmit queue becomes empty, the UART may not have
  4284.                actually transmitted the last of the bytes. A program may need
  4285.                to know when all the data has actually been transmitted so
  4286.                that it may, for example, change the state of the hardware
  4287.                lines. Cport::TxWait will return after the UART has been 
  4288.                emptied of data.
  4289.  
  4290.    See Also    Cport::LenTx
  4291.  
  4292.    Example     Send a string to a half duplex device. This examples assumes
  4293.                that the device is monitoring our RTS line to determine a
  4294.                transmit or receive state.
  4295.  
  4296.                void SendMessage(Cport device, const char* msg)
  4297.                {
  4298.                   device.Rts(ON);
  4299.                   device.Put(msg);
  4300.                   while(device.LenTx());
  4301.                   device.TxWait();
  4302.                   device.Rts(OFF);
  4303.                }
  4304.  
  4305.                                  5-24
  4306.  
  4307.  
  4308.    Status Functions
  4309.    ----------------
  4310.  
  4311.  
  4312.    Basic
  4313.  
  4314.       Cport::Error detects hardware and software errors.
  4315.  
  4316.  
  4317.    Intermediate
  4318.  
  4319.       Cport::Status returns the status of the software and input hardware lines.
  4320.  
  4321.       Cport::Rts  controls the RTS output line.
  4322.  
  4323.       Cport::Dtr controls the DTR output line.
  4324.  
  4325.  
  4326.    Advanced
  4327.  
  4328.       Cport::Out1 controls the general purpose OUT1 output line.
  4329.  
  4330.       Cport::Uart determines what type of UART chip is residing at a serial port.
  4331.  
  4332.                                  5-25
  4333.  
  4334.  
  4335.    Cport::Error
  4336.    ------------------------------------------------------------------
  4337.  
  4338.    Function    Determines if any errors have occurred on a serial port since
  4339.                the last call to Cport::Error.
  4340.  
  4341.    Syntax      #include "cport.h"
  4342.                unsigned Cport::Error();
  4343.  
  4344.    Remarks     Cport::Error determines if any errors are pending on the
  4345.                serial port instance. After a call to Cport::Error, the errors
  4346.                are cleared. Cport::Error returns a bit ORed error word. See
  4347.                Table A-7 on Appendix A for a list of bit definitions.
  4348.  
  4349.    Return value   If an error has occurred, Cport::Error returns an error
  4350.                   word. If no errors have occurred, it returns a 0.
  4351.  
  4352.    See also    Cport::Status
  4353.  
  4354.    Example     Determine the source of the error if one has occurred.
  4355.  
  4356.                #define HARDWARE   (PARITY | FRAMING | BREAK | RX_FIFO)
  4357.  
  4358.                void CheckForErrors(Cport& dvm)
  4359.                {
  4360.                unsigned err;
  4361.  
  4362.                   if((err = dvm.Error()) == 0)
  4363.                      return;
  4364.  
  4365.                   else if(err & OVERUN)
  4366.                   {
  4367.                      // over run error
  4368.                   }
  4369.                   else if(err & HARDWARE)
  4370.                   {
  4371.                      // hardware errors
  4372.                   }
  4373.                   else if(err & (TXFULL | RXFULL))
  4374.                   {
  4375.                      // queue errors
  4376.                   }
  4377.                }
  4378.  
  4379.  
  4380.    Cport::Status
  4381.    ------------------------------------------------------------------
  4382.  
  4383.    Function    Retrieves the status of a serial port's software and hardware
  4384.                lines.
  4385.  
  4386.    Syntax      #include "cport.h"
  4387.                unsigned Cport::Status();
  4388.  
  4389.                                  5-26
  4390.  
  4391.  
  4392.    Remarks     Cport::Status retrieves the status of the serial port
  4393.                instance's software and hardware lines. Cport::Status returns
  4394.                a bit ORed status word. See Table A-8 in Appendix A for a list
  4395.                of bit definitions.
  4396.  
  4397.  
  4398.    Return value   Cport::Status returns the status word of the software and
  4399.                   hardware lines.
  4400.  
  4401.    See also    Cport::Error, Cport::Rts, Cport::Dtr
  4402.  
  4403.    Example     Test if the modem is powered up and ready.
  4404.  
  4405.                #include <dos.h>
  4406.  
  4407.                int CheckModem(Cport& modem)
  4408.                {
  4409.                   modem.Dtr(ON);
  4410.                   delay(40);
  4411.  
  4412.                   return((modem.Status() & DSR) != 0);
  4413.                }
  4414.  
  4415.  
  4416.    Cport::Rts
  4417.    ------------------------------------------------------------------
  4418.  
  4419.    Function    Sets or clears a serial port's Request to Send line.
  4420.  
  4421.    Syntax      #include "cport.h"
  4422.                void Cport::Rts(byte on_off);
  4423.  
  4424.    Parameters
  4425.  
  4426.       on_off - Determines whether RTS is to be set or cleared. See Table A-10
  4427.                in Appendix A.
  4428.  
  4429.    Remarks     Cport::Rts sets or clears the serial port instance's RTS line,
  4430.                depending on the value of on_off. If the value of on_off is
  4431.                ON, RTS is asserted. If the value of on_off is OFF, RTS is
  4432.                inhibited. In many cases, this signal will be looked at by the
  4433.                remote device to determine if it is safe to transmit. This
  4434.                gives the programmer the ability to turn off the remote
  4435.                device's transmitter.
  4436.  
  4437.                NOTE: Cport::Rts should never be called when RTS hardware
  4438.                handshaking is enabled.
  4439.  
  4440.    See also    Cport::Dtr, Cport::Status, Cport::Handshake
  4441.  
  4442.                                  5-27
  4443.  
  4444.  
  4445.    Example     Put the device in an on or off line state. (Assumes the remote
  4446.                device will not send data without our RTS asserted)
  4447.  
  4448.                void OffLine(Cport& device)
  4449.                {
  4450.                   device.Rts(OFF);
  4451.                }
  4452.                void OnLine(Cport& device)
  4453.                {
  4454.                   device.Rts(ON);
  4455.                }
  4456.  
  4457.  
  4458.    Cport::Dtr
  4459.    ------------------------------------------------------------------
  4460.  
  4461.    Function    Sets or clears a serial port's Data Terminal Ready line.
  4462.  
  4463.    Syntax      #include "cport.h"
  4464.                void Cport::Dtr(byte on_off);
  4465.  
  4466.    Parameters
  4467.  
  4468.       on_off - Determines whether DTR is to be asserted or inhibited. See
  4469.                Table A-10 in Appendix A.
  4470.  
  4471.       Remarks  Cport::Dtr set or clears the serial port instance's DTR line,
  4472.                depending on the value of on_off. If the value of on_off is
  4473.                ON, DTR is asserted. If the value of on_off is OFF, DTR is
  4474.                inhibited. In many cases, this signal will be looked at by the
  4475.                remote device to determine if it is safe to transmit. This
  4476.                gives the programmer the ability to turn off the remote
  4477.                device's transmitter.
  4478.  
  4479.                NOTE: Cport::Dtr should never be called when DTR hardware
  4480.                handshaking is enabled.
  4481.  
  4482.    See also    Cport::Rts, Cport::Status, Cport::Handshake
  4483.  
  4484.    Example     Put the device in an on or off line state. (Assumes the remote
  4485.                device will not send data without our DTR asserted).
  4486.  
  4487.                void OffLine(Cport& device)
  4488.                {
  4489.                   device.Dtr(OFF);
  4490.                }
  4491.                void OnLine(Cport& device)
  4492.                {
  4493.                   device.Dtr(ON);
  4494.                }
  4495.  
  4496.                                  5-28
  4497.  
  4498.  
  4499.    Cport::Out1
  4500.    ------------------------------------------------------------------
  4501.  
  4502.    Function    Sets or clears a serial port's Out1 line.
  4503.  
  4504.    Syntax      #include "cport.h"
  4505.                void Cport::Out1(byte on_off);
  4506.  
  4507.    Parameters
  4508.  
  4509.       on_off - Determines whether OUT1 is to be asserted or inhibited. See
  4510.                Table A-10 in Appendix A.
  4511.  
  4512.    Remarks     Cport::Out1 sets or clears the serial port instance's general
  4513.                purpose OUT1 line depending on the value of on_off. If the
  4514.                value of on_off is ON, OUT1 is asserted. If the value of
  4515.                on_off is OFF, OUT1 is inhibited. OUT1 is a general purpose
  4516.                output sometimes utilized by a device for a special feature or
  4517.                reset.
  4518.  
  4519.    See also    Cport::Rts, Cport::Dtr
  4520.  
  4521.    Example     Reset a smart modem.
  4522.  
  4523.                void SmartReset(Cport& modem)
  4524.                {
  4525.                   modem.Out1(ON);
  4526.                   delay(50);
  4527.                   modem.Out1(OFF);
  4528.                }
  4529.  
  4530.  
  4531.    Cport::Uart
  4532.    ------------------------------------------------------------------
  4533.  
  4534.    Function    Determines the type of UART at a serial port.
  4535.  
  4536.    Syntax      #include "cport.h"
  4537.    int Cport::Uart();
  4538.  
  4539.    Remarks     Cport::Uart determines the type of UART chip that resides
  4540.                at the instance's serial port. See Table A-11 for a list of
  4541.                UART types.
  4542.  
  4543.    Return value   Cport::Uart returns a value representative of the type of 
  4544.                   UART that was detected.
  4545.  
  4546.    See Also    Cport::NS550
  4547.  
  4548.    Example     If the serial port instance has an NS16550 UART, set the
  4549.                trigger level to 1 byte.
  4550.  
  4551.                void SetThreshIf550(Cport& com)
  4552.                {
  4553.                   if(com.Uart() == NS16550)
  4554.                      com.NS550(T550_1);
  4555.                }
  4556.                                  5-29
  4557.  
  4558.  
  4559.    Data Integrity
  4560.    --------------
  4561.  
  4562.    Intermediate
  4563.  
  4564.       Cport::Checksum calculates a byte checksum of a block of data.
  4565.  
  4566.       Cport::Crc16 calculates a 16 bit cyclic redundancy check (CRC) on a
  4567.       block of data.
  4568.  
  4569.       Cport::Crc32.calculates a 32 bit cyclic redundancy check (CRC) on a
  4570.       block of data.
  4571.  
  4572.                                  5-30
  4573.  
  4574.  
  4575.    Cport::Checksum
  4576.    ------------------------------------------------------------------
  4577.  
  4578.    Function    Performs a byte checksum calculation on a block of data.
  4579.  
  4580.    Syntax      #include "cport.h"
  4581.                static byte Cport::Checksum(const void *abyte, unsigned nbyte);
  4582.  
  4583.    Parameters
  4584.  
  4585.       abyte  - Pointer to the block on which the checksum is to be performed.
  4586.  
  4587.       nbyte  - Number of bytes in the block.
  4588.  
  4589.    Remarks     Cport::Checksum performs a byte checksum on the block of bytes
  4590.                pointed to by abyte. The checksum is calculated by summing all
  4591.                the bytes in the block.
  4592.  
  4593.    Return value   Cport::Checksum returns a one byte checksum.
  4594.  
  4595.    See also    Cport::Crc16, Cport::Crc32, Cport::In, Cport::Out
  4596.  
  4597.    Example     Verify that the actual checksum matches the received checksum.
  4598.  
  4599.                struct Xblock
  4600.                {
  4601.                   byte num;
  4602.                   byte _num;
  4603.                   byte data[128];
  4604.                   byte checksum;
  4605.                }block;
  4606.  
  4607.                int GetXblock(Cport& com, Xblock& block)
  4608.                {
  4609.                   com.In(&block, sizeof(Xblock));
  4610.  
  4611.                   if((com.Checksum(block.data, 128) - block.checksum) != 0)
  4612.                      return(-1);
  4613.                   else
  4614.                      return(0);
  4615.                }
  4616.  
  4617.  
  4618.    Cport::Crc16
  4619.    ------------------------------------------------------------------
  4620.  
  4621.    Function    Performs a 16 bit cyclic redundancy check on a block of data.
  4622.  
  4623.    Syntax      #include "cport.h"
  4624.                static unsigned ComCrc16(const void *abyte, unsigned nbyte);
  4625.  
  4626.    Parameters
  4627.  
  4628.       abyte  - Pointer to the block on which the 16 bit cyclic redundancy
  4629.                check is to be performed.
  4630.  
  4631.                                  5-31
  4632.  
  4633.  
  4634.       nbyte  - Number of bytes in the block.
  4635.  
  4636.  
  4637.    Remarks     Cport::Crc16 performs a 16 bit cyclic redundancy check on the
  4638.                block of data pointed to by abyte.
  4639.  
  4640.    Return value   Cport::Crc16 returns the 16 bit CRC value.
  4641.  
  4642.    See also    Cport::Crc32, Cport::Checksum, Cport::In, Cport::Out
  4643.  
  4644.    Example     Verify that the actual CRC matches the received CRC.
  4645.  
  4646.                struct Xblock{
  4647.                   byte num;
  4648.                   byte _num;
  4649.                   byte data[128];
  4650.                   unsigned crc;
  4651.                   }block;
  4652.  
  4653.                int GetXblock(Cport& com, Xblock& block)
  4654.                {
  4655.                   com.In(&block, sizeof(Xblock));
  4656.  
  4657.  
  4658.                      // Check the calculated CRC against the block CRC.
  4659.                      //
  4660.                   if(com.Crc16(block.data, 128) != block.crc)
  4661.                      return(-1);
  4662.                   else
  4663.                      return(0);
  4664.                }
  4665.  
  4666.  
  4667.    Cport::Crc32
  4668.    ------------------------------------------------------------------
  4669.  
  4670.    Function    Performs a 32 bit cyclic redundancy check on a block of data.
  4671.  
  4672.    Syntax      #include "cport.h"
  4673.                static unsigned long ComCrc32(const void *abyte, unsigned nbyte);
  4674.  
  4675.    Parameters
  4676.  
  4677.       abyte  - Pointer to the block on which the 32 bit cyclic redundancy
  4678.                check is to be performed.
  4679.  
  4680.       nbyte  - Number of bytes in the block.
  4681.  
  4682.    Remarks     Cport::Crc32 performs a 32 bit cyclic redundancy check on the
  4683.                block of data pointed to by abyte.
  4684.  
  4685.    Return value   Cport::Crc32 returns the 32 bit CRC value.
  4686.  
  4687.    See also    Cport::Crc16, Cport::Checksum, Cport::In, Cport::Out
  4688.  
  4689.                                  5-32
  4690.  
  4691.  
  4692.    Example     Verify that the actual CRC matches the received CRC.
  4693.  
  4694.                struct Packet {
  4695.                   byte num;
  4696.                   byte data[1024];
  4697.                   unsigned long crc;
  4698.                   }packet;
  4699.  
  4700.                int GetPacket(Cport& com, Packet& packet)
  4701.                {
  4702.                   com.In(&packet, sizeof(Packet));
  4703.  
  4704.                      // Check the calculated CRC against the packet's CRC.
  4705.                      //
  4706.                   if(com.Crc32(packet.data, 1024) != packet.crc)
  4707.                      return(-1);
  4708.                   else
  4709.                      return(0);
  4710.                }
  4711.  
  4712.                                  5-33
  4713.  
  4714.  
  4715.    Misc Functions
  4716.    --------------
  4717.  
  4718.    Advanced
  4719.  
  4720.       Cport::SetBreak sets a break condition.
  4721.  
  4722.       Cport::ClrBreak clears a break condition.
  4723.  
  4724.       Cport::Scratch writes to or reads from the UART's scratch register.
  4725.  
  4726.                                  5-34
  4727.  
  4728.  
  4729.    Cport::SetBreak
  4730.    ------------------------------------------------------------------
  4731.  
  4732.    Function    Set a break condition on a serial port.
  4733.  
  4734.    Syntax      #include "cport.h"
  4735.                void Cport::SetBreak();
  4736.  
  4737.    Remarks     Cport::SetBreak sets a break condition on the serial port
  4738.                instance. The break condition will stay in effect until a
  4739.                subsequent call to Cport::ClrBreak is made.
  4740.  
  4741.    See also    Cport::ClrBreak
  4742.  
  4743.    Example     If the an abort condition has been declared, set a break
  4744.                condition. When it clears, release the break condition.
  4745.  
  4746.                void Abort(Cport& com, int abrt)
  4747.                {
  4748.                static int brkflg;
  4749.  
  4750.                   if(abrt && !brkflg)
  4751.                      com.SetBreak();
  4752.  
  4753.                   else if(!abrt && brkflg)
  4754.                      com.ClrBreak();
  4755.                }
  4756.  
  4757.  
  4758.    Cport::ClrBreak
  4759.    ------------------------------------------------------------------
  4760.  
  4761.    Function    Clears a previously set break condition on a serial port.
  4762.  
  4763.    Syntax      #include "cport.h"
  4764.                void Cport::ClrBreak();
  4765.  
  4766.    Remarks     Cport::ClrBreak clears a previously set break condition on the
  4767.                serial port instance.
  4768.  
  4769.    See also    Cport::SetBreak
  4770.  
  4771.    Example     If the an abort condition has been declared, set a break
  4772.                condition. When it clears, release the break condition.
  4773.  
  4774.                void Abort(Cport& com, int abrt)
  4775.                {
  4776.                static int brkflg;
  4777.  
  4778.                   if(abrt && !brkflg)
  4779.                      com.SetBreak();
  4780.  
  4781.                   else if(!abrt && brkflg)
  4782.                      com.ClrBreak();
  4783.                }
  4784.  
  4785.                                  5-35
  4786.  
  4787.  
  4788.    Cport::Scratch
  4789.    ------------------------------------------------------------------
  4790.  
  4791.    Function    Writes a byte to, or reads a byte from the serial port's
  4792.                scratch register.
  4793.  
  4794.    Syntax      #include "cport.h"
  4795.                void Cport::Scratch(byte abyte);
  4796.  
  4797.                or
  4798.  
  4799.                byte Cport::Scratch();
  4800.  
  4801.    Parameters
  4802.  
  4803.       abyte  - The byte to be written to the scratch register.
  4804.  
  4805.    Remarks     If a parameter is specified, Cport::Scratch writes the byte
  4806.                value abyte to the serial port instance's UART scratch
  4807.                register. If Cport::Scratch is called with no parameters, it
  4808.                reads the byte in the UART scratch register. Not all UARTs
  4809.                have a scratch register.
  4810.  
  4811.    Example     Exchange a value with the scratch register.
  4812.  
  4813.                byte ScratchExchange(Cport& com, byte value)
  4814.                {
  4815.                byte rv;
  4816.  
  4817.                   rv = com.Scratch();      // read the scratch register
  4818.                   com.Scratch(value);   // write to the scratch register
  4819.                   return(rv);
  4820.                }
  4821.  
  4822.                                  6-1
  4823.  
  4824.  
  4825. File Transfer
  4826. =============
  4827.  
  4828.    Xmodem
  4829.    ------
  4830.  
  4831.       XmodemTx transmits a file using the Xmodem file transfer protocol.
  4832.  
  4833.       XmodemRx receives a file using the Xmodem file transfer protocol.
  4834.  
  4835.       Xcallback is the default callback function for XmodemTx and XmodemRx.
  4836.  
  4837.                                 6-2
  4838.  
  4839.  
  4840.    XmodemTx
  4841.    ------------------------------------------------------------------
  4842.  
  4843.    Function    Transmits a file with the Xmodem file transfer protocol.
  4844.  
  4845.    Syntax      #include "xmodem.h"
  4846.                int XmodemTx(COM, const char* file,
  4847.                                           int (*cb)(int msg, XPARAM param));
  4848.                or
  4849.                int XmodemTx(Cport&, const char* file,
  4850.                                           int (*cb)(int msg, XPARAM param));
  4851.    Parameters
  4852.  
  4853.       COM    - Handle of the serial port (C).
  4854.  
  4855.       Cport  - Reference to a serial port instance (C++).
  4856.  
  4857.       file   - Path/name of the file to be transferred.
  4858.  
  4859.       cb     - Pointer to the callback function.
  4860.  
  4861.    Remarks     XmodemTx transmits the file file via the serial port specified
  4862.                by COM or Cport. It will make calls back to the function cb if
  4863.                one is specified. If you specify NULL for cb, a default
  4864.                callback function will be used. See the following discussion
  4865.                on the callback function for a complete explanation of the
  4866.                callback function.
  4867.  
  4868.    Return value   XmodemTx returns zero if the file was transferred
  4869.                   successfully. Otherwise, it returns non-zero. See Table 
  4870.                   6-1 for a list of return codes.
  4871.  
  4872.    See also    XmodemRx, Xcallback
  4873.  
  4874.    Example     Transfer the file cport.zip via the modem. (C)
  4875.  
  4876.                                 /* callback function prototype */
  4877.                int myCallback(int msg, XPARAM param);
  4878.  
  4879.                int main(void)
  4880.                {
  4881.                COM modem;
  4882.                int rv;
  4883.  
  4884.                   modem = ComOpen(COM1, B2400, W8|S1|NONE, 1024, 512);
  4885.                   if(comopen_errno != NO_ERR)
  4886.                      return(-comopen_errno);
  4887.  
  4888.                   rv = XmodemTx(modem, "cport.zip", myCallback);
  4889.                   ComClose(modem);
  4890.                   return(rv);
  4891.                }
  4892.  
  4893.                                  6-3
  4894.  
  4895.  
  4896.    Example     Transfer the file cport.zip via the modem. (C++)
  4897.  
  4898.                                              // callback function prototype
  4899.                int myCallback(int msg, XPARAM param);
  4900.                int main(void)
  4901.                {
  4902.                   Cport modem(COM1, B2400);  // uses default parameters
  4903.                   if((int)modem != NO_ERR)
  4904.                      return(-((int)modem));
  4905.  
  4906.                   return(XmodemTx(modem, "cport.zip", myCallback));
  4907.                }
  4908.  
  4909.  
  4910.    XmodemRx
  4911.    ------------------------------------------------------------------
  4912.  
  4913.    Function    Receives a file with the Xmodem file transfer protocol.
  4914.  
  4915.    Syntax      #include "xmodem.h"
  4916.                int XmodemRx(COM, const char* file,
  4917.                                           int (*cb)(int msg, XPARAM param));
  4918.                or
  4919.                int XmodemRx(Cport&, const char* file,
  4920.                                           int (*cb)(int msg, XPARAM param));
  4921.  
  4922.    Parameters
  4923.  
  4924.       COM    - Handle of the serial port (C).
  4925.  
  4926.       Cport  - Reference to a serial port instance (C++).
  4927.  
  4928.       file   - Path/name of the file to be transferred.
  4929.  
  4930.       cb     - Pointer to the callback function.
  4931.  
  4932.  
  4933.  
  4934.    Remarks     XmodemRx receives the file file via the serial port specified
  4935.                by COM or Cport. It will make calls back to the function cb
  4936.                if one is specified. If you specify NULL for cb, a default
  4937.                callback function will be used. See the following discussion
  4938.                on the callback function for a complete explanation of the
  4939.                callback function.
  4940.  
  4941.  
  4942.  
  4943.    Return value   XmodemTx returns zero if the file was transferred
  4944.                   successfully. Otherwise, it returns non-zero. See Table 
  4945.                   6-1 for a list of return codes.
  4946.  
  4947.    See also    XmodemTx, Xcallback
  4948.  
  4949.                                  6-4
  4950.  
  4951.  
  4952.    Example     Receive the file cport.zip via the modem. (C)
  4953.  
  4954.                                         /* callback function prototype */
  4955.                int myCallback(int msg, XPARAM param);
  4956.  
  4957.                int main(void)
  4958.                {
  4959.                COM modem;
  4960.                int rv;
  4961.  
  4962.                   modem = ComOpen(COM1, B2400, W8|S1|NONE, 1024, 512);
  4963.                   if(comopen_errno != NO_ERR)
  4964.                      return(-comopen_errno);
  4965.  
  4966.                   rv = XmodemRx(modem, "cport.zip", myCallback);
  4967.                   ComClose(modem);
  4968.                   return(rv);
  4969.                }
  4970.  
  4971.    Example     Receive the file cport.zip via the modem. (C++)
  4972.  
  4973.                                          // callback function prototype
  4974.                int myCallback(int msg, XPARAM param);
  4975.  
  4976.                int main(void)
  4977.                {
  4978.                   Cport modem(COM1, B2400);  // uses default parameters
  4979.                   if((int)modem != NO_ERR)
  4980.                      return(-((int)modem));
  4981.  
  4982.                   return(XmodemRx(modem, "cport.zip", myCallback));
  4983.                }
  4984.  
  4985.  
  4986.    Xcallback
  4987.    ------------------------------------------------------------------
  4988.  
  4989.    Function    Default callback function.
  4990.  
  4991.    Syntax      #include "xmodem.h"
  4992.                int Xcallback(int msg, XPARAM param);
  4993.  
  4994.    Parameters
  4995.  
  4996.       msg    - Callback message number. (See Table 6-2).
  4997.  
  4998.       param  - Message specific parameter. (See Table 6-2 and 6-3)
  4999.  
  5000.    Remarks     Xcallback is the default Xmodem callback function. When NULL
  5001.                is specified as the callback function in a call to XmodemTx
  5002.                or XmodemRx, Xcallback will be used. Xcallback only keeps
  5003.                track of errors to decide if the transfer should be aborted.
  5004.                You can chain callback functions by specifying a callback
  5005.                function and then calling Xcallback directly. You would do
  5006.                this if you were only interested in the information provided
  5007.  
  5008.                                  6-5
  5009.  
  5010.  
  5011.                to the callback function and did not want to affect the
  5012.                functionality of the transfer.
  5013.  
  5014.  
  5015.    Return value   When a callback function returns zero, the transfer
  5016.                   continues. If it returns non-zero, the transfer is
  5017.                   canceled, and XmodemRx or XmodemTx will return with a
  5018.                   non-zero return code.
  5019.  
  5020.    See also    XmodemTx, XmodemRx
  5021.  
  5022.    Example     Use the default callback when receiving the file cport.zip
  5023.                via the modem. This results in a blind transfer.
  5024.  
  5025.                int main(void)
  5026.                {
  5027.                COM modem;
  5028.                int rv;
  5029.  
  5030.                   modem = ComOpen(COM1, B2400, W8|S1|NONE, 1024, 512);
  5031.                   if(comopen_errno != NO_ERR)
  5032.                      return(-comopen_errno);
  5033.  
  5034.                   rv = XmodemRx(modem, "cport.zip", NULL);
  5035.                   ComClose(modem);
  5036.                   return(rv);
  5037.                }
  5038.  
  5039.    Example     Establish a callback function for procuring information for
  5040.                screen updates only.
  5041.  
  5042.                int myCallback(int msg, XPARAM param)
  5043.                {
  5044.                   switch(msg)
  5045.                   {
  5046.                      case XM_BLOCKCHECK:
  5047.                         /* Update the screen */
  5048.                         break;
  5049.  
  5050.                      case XM_BLOCK:
  5051.                         /* Update the screen */
  5052.                         break;
  5053.  
  5054.                      case...
  5055.                   }
  5056.                      /* chain to the default callback for functionality
  5057.                       */
  5058.                   return(Xcallback(msg, param));
  5059.                }
  5060.  
  5061.    Callback Function
  5062.    ------------------------------------------------------------------
  5063.    Since it usually takes time to transfer a file, there must be a mechanism
  5064.    for monitoring and optionally canceling the transfer. To accomplish this,
  5065.    the Xmodem transmit and receive functions accept a parameter, which is a
  5066.    pointer  to a callback function. This function will be called at certain
  5067.  
  5068.                                  6-6
  5069.  
  5070.  
  5071.    points during the file transfer. Your callback function can be used to
  5072.    update the screen, cancel the transfer, etc. Your callback function must
  5073.    have the exact prototype:
  5074.  
  5075.    int function_name(int msg, XPARAM param);
  5076.  
  5077.    Msg is the message number that identifies why the callback was made.
  5078.    The value of param depends on the message. It provides additional
  5079.    information for a specific message. Anytime param is not used, it is set
  5080.    to zero. The following is a list of messages and their descriptions.
  5081.  
  5082.    XM_IDLE (0) - Idle time. This message is sent during idle time to give
  5083.       the callback the opportunity to do something, such as checking to see
  5084.       if the user wishes to cancel the transfer.
  5085.  
  5086.    XM_START (1) - Start of transfer. This message is sent, at most, one time.
  5087.       It signals that the transfer has been successfully prepared and will
  5088.       now attempt to make contact with the remote station.
  5089.  
  5090.    XM_BLOCKCHECK (2) - Block check determined. Once the block check has
  5091.       been determined, this message is sent to inform the callback if the
  5092.       block check will be checksum (param == 0) or CRC16 (param != 0). This
  5093.       message is sent, at most, one time during a transfer. It is mostly
  5094.       informative .
  5095.  
  5096.    XM_BLOCK (3) - New block transferred. This message is sent each time a new
  5097.       block (128 bytes) is successfully transferred. For this message, param
  5098.       contains the block number. This message is primarily an informative
  5099.       message.
  5100.  
  5101.    XM_EOT (4) - End of transmission. This message is sent when an end of
  5102.       transmission is being established. Usually there will be only one of
  5103.       these messages, however, if problems arise, the EOT may be retried.
  5104.  
  5105.    XM_DONE (5) - Transfer done. This message is sent at the end of a
  5106.       transmission whether the transmission was successful or canceled. It
  5107.       is sent exactly one time if XM_START was previously sent. Otherwise, 
  5108.       it will not be sent.
  5109.  
  5110.    XM_ERROR (6) - Error detected. This message is sent when an error is
  5111.       detected in the data. Param contains the error code. The lower 12 bits
  5112.       of param is the bit ORed errors returned by the function ComError.
  5113.       The upper 4 bits is the extended Xmodem error code (not bit ORed).
  5114.       The extended Xmodem error code (upper 4 bits) should always be
  5115.       non-zero. The ComError bits (lower 12 bits) may or may not indicate
  5116.       errors. Usually the ComError portion of the error code takes precedence
  5117.       over the extended Xmodem code, since it is likely to be the source of
  5118.       the error. The extended Xmodem errors are explained here. See ComError
  5119.       or Cport::Error for information on the lower 12 bits of the error code:
  5120.  
  5121.    XE_BADBLOCK (0x1000) - Bad block. This error occurs when a block was
  5122.       determined to be corrupted. Occasional bad block errors may occur. If
  5123.       the transfer is not canceled by the callback function, Xmodem will
  5124.       attempt to recover from this error (usually succeeding) by retrying
  5125.       the block.
  5126.  
  5127.                                  6-7
  5128.  
  5129.  
  5130.    XE_BADCHECK (0x2000) - Bad block check. This error occurs when the block
  5131.       is not detected as bad (XE_BADBLOCK) but the block check (CRC or
  5132.       checksum) does not match the data. This error can only be detected
  5133.       when receiving a file.
  5134.  
  5135.    XE_TIMEOUT (0x3000) - Timeout. Xmodem timed out waiting for a block or
  5136.       for protocol exchange. If the callback function does not cancel the
  5137.       transfer, Xmodem will retry whatever timed out. Successful recovery
  5138.       from this error depends on the reason (usually unknown) for the timeout.
  5139.  
  5140.    XE_CANCEL (0x4000) - Transmission canceled. This message is sent when
  5141.       the transmission is canceled by either the callback function, by the
  5142.       remote station or for other internal reasons.
  5143.  
  5144.  
  5145.    Xmodem Tables of Values
  5146.    ------------------------------------------------------------------
  5147.  
  5148.  
  5149.  
  5150.                name        value       description
  5151.                -----------------------------------------------
  5152.                XR_NOERR    (0)         No error.
  5153.                XR_FILEERR  (1)         File error.
  5154.                XR_CANCEL   (2)         Transfer canceled.
  5155.                XR_ALLOC    (3)         Memory allocation error.
  5156.  
  5157.                Table 6-1 - XmodemRx/XmodemTx return values.
  5158.  
  5159.  
  5160.  
  5161.    name           value    description             XPARAM
  5162.    -------------------------------------------------------------------------
  5163.    XM_IDLE        (0)      Idle time.              0.
  5164.    XM_START       (1)      Start of transfer       0.
  5165.    XM_BLOCKCHECK  (2)      Block check determined  0 if checksum, 1 if CRC16.
  5166.    XM_BLOCK       (3)      New block transferred   Block number.
  5167.    XM_EOT         (4)      End of transmission     0.
  5168.    XM_DONE        (5)      Transfer complete       0.
  5169.    XM_ERROR       (6)      Error has been detected Error code.
  5170.  
  5171.                   Table 6-2 - Xmodem callback messages.
  5172.  
  5173.  
  5174.  
  5175.             name           value       description
  5176.             ------------------------------------------------------------
  5177.             XE_BADBLOCK    (0x1000)    Bad block.
  5178.             XE_BADCHECK    (0x2000)    Bad block check (CRC or checksum).
  5179.             XE_TIMEOUT     (0x3000)    Timeout.
  5180.             XE_CANCEL      (0x4000)    Transfer canceled.
  5181.  
  5182.                Table 6-3 - Extended Xmodem error codes.
  5183.  
  5184.                                  A-1
  5185.  
  5186.  
  5187. Appendix A
  5188. ==========
  5189.  
  5190.                      name     value
  5191.                      -----------------------
  5192.                      * COM1   (PORT0 | IRQ4)
  5193.                      * COM2   (PORT1 | IRQ3)
  5194.                      * COM3   (PORT2 | IRQ4)
  5195.                      * COM4   (PORT3 | IRQ3)
  5196.  
  5197.                      PORT0    (0x03F8)
  5198.                      PORT1    (0x02F8)
  5199.                      PORT2    (0x03E8)
  5200.                      PORT3    (0x02E8)
  5201.  
  5202.                      IRQ2     (0x2000)
  5203.                      IRQ3     (0x3000)
  5204.                      IRQ4     (0x4000)
  5205.                      IRQ5     (0x5000)
  5206.                      IRQ6     (0x6000)
  5207.                      IRQ7     (0x7000)
  5208.  
  5209.                      BIOS0    (*(int far *)0x400000l)
  5210.                      BIOS1    (*(int far *)0x400002l)
  5211.                      BIOS2    (*(int far *)0x400004l)
  5212.                      BIOS3    (*(int far *)0x400006l)
  5213.  
  5214.                      * The COMx constants are usually sufficient.
  5215.  
  5216.                      Table A-1 - Serial port id.
  5217.  
  5218.  
  5219.  
  5220.                      name     value
  5221.                      ---------------
  5222.                      B115200  (1)
  5223.                      B57600   (2)
  5224.                      B38400   (3)
  5225.                      B19200   (6)
  5226.                      B9600    (12)
  5227.                      B7200    (16)
  5228.                      B4800    (24)
  5229.                      B3600    (32)
  5230.                      B2400    (48)
  5231.                      B2000    (58)
  5232.                      B1800    (64)
  5233.                      B1200    (96)
  5234.                      B600     (192)
  5235.                      B300     (384)
  5236.                      B150     (768)
  5237.                      B110     (1047)
  5238.                      B75      (1536)
  5239.                      B50      (2304)
  5240.  
  5241.                      Table A-2 - Baud rate divisors.
  5242.  
  5243.                                  A-2
  5244.  
  5245.  
  5246.  
  5247.                      name     value    description
  5248.                      ----------------------------------------
  5249.                      W8       (0x03)   8 bit words.
  5250.                      W7       (0x02)   7 bit words.
  5251.                      W6       (0x01)   6 bit words.
  5252.                      W5       (0x00)   5 bit words.
  5253.  
  5254.                      S1       (0x00)   1 stop bit.
  5255.                      S2       (0x04)   2 stop bits.
  5256.  
  5257.                      NONE     (0x00)   No parity.
  5258.                      ODD      (0x08)   Odd parity.
  5259.                      EVEN     (0x18)   Even parity.
  5260.                      MARK     (0x28)   Mark parity (logic 1).
  5261.                      SPACE    (0x38)   Space parity (logic 0).
  5262.  
  5263.                      WMASK    (0x03)   Word mask.
  5264.                      SMASK    (0x04)   Stop bit mask.
  5265.                      PMASK    (0x38)   Parity mask.
  5266.  
  5267.                      Table A-3 - Bit ORed mode components.
  5268.  
  5269.  
  5270.  
  5271.          name     value    description
  5272.          ---------------------------------------------------------------
  5273.          NO_ERR   (0)      No errors.
  5274.          OPENED   (1)      Serial port is already opened.
  5275.          BAD_ID   (2)      Invalid id parameter.
  5276.          NO_UART  (3)      No UART chip was detected.
  5277.          RX_ALC   (4)      Receive queue allocation error.
  5278.          TX_ALC   (5)      Transmit queue allocation error.
  5279.          MAX_PORT (6)      The maximum number of serial ports are opened.
  5280.          IRQ_CTN  (7)      The irq contends with another open serial port.
  5281.          GEN_ALC  (8)      General memory allocation error.
  5282.  
  5283.                      Table A-4 - Open error values.
  5284.  
  5285.  
  5286.  
  5287.                   name     value    description
  5288.                   ---------------------------------------------------
  5289.                   OFF      (0x00)   No handshaking.
  5290.                   DTR      (0x01)   The receiver uses DTR.
  5291.                   RTS      (0x02)   The receiver uses RTS.
  5292.                   S_RX     (0x04)   The receiver uses XON/XOFF.
  5293.                   CTS      (0x10)   CTS is checked by the transmitter.
  5294.                   DSR      (0x20)   DSR is checked by the transmitter.
  5295.                   DCD      (0x80)   DCD is checked by the transmitter.
  5296.                   S_TX     (0x08)   The transmitter honors XON/XOFF.
  5297.                   SOFT     (0x0C)   Same as  (S_RX | S_TX).
  5298.                   HARD1    (0x21)   Same as  (DTR | DSR).
  5299.                   HARD2    (0x12)   Same as  (RTS | CTS).
  5300.  
  5301.                      Table A-5 - Bit ORed handshaking options.
  5302.  
  5303.                                  A-3
  5304.  
  5305.  
  5306.  
  5307.                   name     value    description
  5308.                   -----------------------------------
  5309.                   TIMER    (0x01)   divert timer (irq0).
  5310.                   KEYBOARD (0x02)   disable keyboard (irq1).
  5311.                   CASCADE  (0x04)   disable irq2.
  5312.                   OFF      (0x00)   restore all interrupts.
  5313.  
  5314.                      Table A-6 - Turbo options.
  5315.  
  5316.  
  5317.  
  5318.                      name     value    description
  5319.                      -----------------------------------------
  5320.                      OVERUN   (0x0002) Overrun error.
  5321.                      PARITY   (0x0004) Parity error.
  5322.                      FRAMING  (0x0008) Framing error.
  5323.                      BREAK    (0x0010) Break detect.
  5324.                      RX_FIFO  (0x0080) Rx fifo error.
  5325.                      TXFULL   (0x0100) Transmit queue overflow.
  5326.                      RXFULL   (0x0200) Receive queue overflow.
  5327.                      (unused) (0xF000) Designated as unused.
  5328.  
  5329.                      Table A-7 - Bit ORed error code.
  5330.  
  5331.  
  5332.  
  5333.                   name     value    description
  5334.                   -----------------------------------------------
  5335.                   DCTS     (0x001)  Change in clear to send.
  5336.                   DDSR     (0x002)  Change in data set ready.
  5337.                   TERI     (0x004)  Trailing edge ring indicator.
  5338.                   DDCD     (0x008)  Change in data carrier detect.
  5339.                   CTS      (0x010)  Clear to send asserted.
  5340.                   DSR      (0x020)  Data set ready asserted.
  5341.                   RI       (0x040)  Ring indicator asserted.
  5342.                   DCD      (0x080)  Data carrier detect asserted.
  5343.                   S_TX_OFF (0x100)  Transmitter off (XOFF state).
  5344.                   U_TX_OFF (0x200)  Transmitter off (ComTx).
  5345.                   S_RX_OFF (0x400)  Receiver off (XOFF state).
  5346.  
  5347.                      Table A-8 - Bit ORed status word.
  5348.  
  5349.  
  5350.  
  5351.                   name        value    description
  5352.                   ----------------------------------------------
  5353.                   ON          (1)      Turns the transmitter on.
  5354.                   OFF         (0)      Turns the transmitter off.
  5355.                   TX_DIRECT   (0x2)    Use direct mode when off.
  5356.  
  5357.                      Table A-9 - Transmitter options.
  5358.  
  5359.                                  A-4
  5360.  
  5361.  
  5362.                   name        value    description
  5363.                   -------------------------------------
  5364.                   ON          (1)      Signal asserted.
  5365.                   OFF         (0)      Signal inhibited.
  5366.  
  5367.                      Table A-10 - On/off values.
  5368.  
  5369.  
  5370.  
  5371.                   name     value    description
  5372.                   --------------------------------------
  5373.                   INS8250  (1)      INS8250 or INS8250-B.
  5374.                   NS16450  (2)      NS16450 or INS8250A.
  5375.                   NS16550  (3)      NS16550.
  5376.                   I82510   (4)      82510 (Intel).
  5377.  
  5378.                         Table A-11 - UART types.
  5379.  
  5380.  
  5381.  
  5382.                   name     value    description
  5383.                   --------------------------------
  5384.                   T550_1   (0x00)   1 byte.
  5385.                   T550_4   (0x400   4 bytes.
  5386.                   T550_8   (0x80)   8 bytes.
  5387.                   T550_14  (0xC0)   14 bytes.
  5388.  
  5389.                   Table A-12- NS550 trigger thresholds.
  5390.  
  5391.                                  B-1
  5392.  
  5393.  
  5394. Appendix B
  5395. ==========
  5396.  
  5397.    Compiling
  5398.    ---------
  5399.       1) Make sure the header file(s) are included in any modules (source
  5400.          files) which make calls to Cport library functions.
  5401.  
  5402.          Example: #include "cport.h"
  5403.  
  5404.       2) Make sure your compiler knows where to find the header file(s).
  5405.  
  5406.          Borland C/C++: bcc -c -Ic:\cport\include your_file
  5407.  
  5408.          Microsoft C/C++: cl /c /Ic:\cport\include your_file
  5409.  
  5410.          NOTE: cl will also look at the INCLUDE environment variable for
  5411.                the include directories.
  5412.  
  5413.          Example: set INCLUDE=c:\c600\include;c:\cport\include;
  5414.  
  5415.       3) Make sure your compiler is generating byte alignments when generating
  5416.          structures. This is only a concern when using Cport functions, which
  5417.          involve structures such as CPARAM. For Borland and Microsoft
  5418.          compilers, this is taken care of. If you are using another compiler, 
  5419.          consult your user's manual on how to generate byte alignments.
  5420.  
  5421.          Borland C/C++: (uses byte alignment by default)
  5422.  
  5423.          Microsoft C/C++: cl /c /Zp1 /Ic:\cport\include your_file
  5424.  
  5425.    Linking
  5426.    -------
  5427.       1) Make sure the appropriate Cport library is included in the list of
  5428.          libraries. The last letter in the file name of the libraries
  5429.          indicates the memory model:
  5430.  
  5431.             cports.lib - small model
  5432.             cportm.lib - medium model
  5433.             cportc.lib - compact model
  5434.             cportl.lib - large model
  5435.             cporth.lib - huge model
  5436.  
  5437.       2) Make sure the linker knows where to find the library files.
  5438.  
  5439.    Borland C/C++: tlink /Lc:\cport\lib c0s objs, exe_name, map_name, cports cs
  5440.  
  5441.    Microsoft C/C++: link  objs, exe_name, map_name, cports slibce;
  5442.  
  5443.          NOTE: link looks at the LIB environment variable for the library
  5444.          directories:
  5445.  
  5446.          Example: set LIB=c:\c600\lib;c:\cport\lib;
  5447.  
  5448.                                  C-1
  5449.  
  5450.  
  5451. Appendix C
  5452. ==========
  5453.  
  5454. Cport v2.0 Order Form
  5455.  
  5456.    Name: ___________________________________________________________
  5457.  
  5458.    Company: ________________________________________________________
  5459.  
  5460.    Address: ________________________________________________________
  5461.  
  5462.    City: _________________________________  State: _________________
  5463.  
  5464.    Zip Code: _________________  Phone # : __________________________
  5465.  
  5466.    CompuServe # : __________________________________________________
  5467.  
  5468.    How did you acquire Cport ? _____________________________________
  5469.  
  5470.  
  5471.    Compiler(s): ____________________________________________________
  5472.  
  5473.    Computer(s): ____________________________________________________
  5474.  
  5475.    Operating system(s): ____________________________________________
  5476.  
  5477.  
  5478.                  Single Licence .... $65.00
  5479.  
  5480.                  2 Licenses ........ $59.00 each
  5481.  
  5482.                  3 to 4 Licenses ... $54.00 each
  5483.  
  5484.                  5 to 9 licenses ... $48.00 each
  5485.  
  5486.                  10+ licenses ...... $41.00 each
  5487.  
  5488.                  Quantity          price each
  5489.  
  5490.    Subtotal      _________    X    __________   =    $________
  5491.  
  5492.    California residents add sales tax    ( 8.25% )   $________
  5493.  
  5494.    Shipping outside continental U.S. add ( $ 5.00)   $________
  5495.  
  5496.                                             Total:   $________
  5497.    All Payments Must be in U.S. Dollars
  5498.  
  5499.    Make check or money order payable to:    Bri Productions
  5500.                                             P.O. Box 7121
  5501.                                             Fremont, CA 94537-7121
  5502.  
  5503.  
  5504.    Other payment/shipping arrangements may be available.
  5505.  
  5506.                                  C-2
  5507.  
  5508.  
  5509. We want to hear from you!
  5510. -------------------------
  5511. In order to improve Cport and add valuable features, we need to know what
  5512. features you need most. This information is important in order to provide
  5513. you with the best possible product. Please take a moment to answer the
  5514. following questions.
  5515.  
  5516. Indicate your need for the following features by checking the choice
  5517. which best describes your need for the feature:
  5518.  
  5519.                                  very    |  nice   |  don't
  5520.                                important | to have | need it
  5521.                               -----------  -------- ---------
  5522.  
  5523.       Multi port Serial Boards:   ____      ____      ____
  5524.  
  5525.   Board name(s) ______________
  5526.  
  5527.                  Modem support:   ____      ____      ____
  5528.  
  5529.  
  5530.           Zmodem file transfer:   ____      ____      ____
  5531.  
  5532.  
  5533. Other file transfer __________:   ____      ____      ____
  5534.  
  5535.  
  5536. Other file transfer __________:   ____      ____      ____
  5537.  
  5538.  
  5539.                Windows support:   ____      ____      ____
  5540.  
  5541.  
  5542. Other ________________________:   ____      ____      ____
  5543.  
  5544.  
  5545. Other ________________________:   ____      ____      ____
  5546.  
  5547.  
  5548. Other ________________________:   ____      ____      ____
  5549.  
  5550.  
  5551.  
  5552.    What other types of libraries would you find useful ? _____
  5553.  
  5554.    ___Game Port   ___Expanded Memory   ___Sound effects
  5555.  
  5556.    Others______________________________________________________
  5557.  
  5558.    Other Comments______________________________________________
  5559.  
  5560.    ____________________________________________________________
  5561.  
  5562.    ____________________________________________________________
  5563.  
  5564. Bri Productions, P.O. Box 7121, Fremont, CA  94537, (510) 794-0616
  5565.  
  5566.  
  5567.  
  5568.